如何泡在我的ViewModel层次的变化? [英] How to bubble up changes in my ViewModel hierarchy?

查看:226
本文介绍了如何泡在我的ViewModel层次的变化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的MainView.xaml包含我的智能表查看:

My MainView.xaml contains my SmartForm View:

<Grid Margin="10">
    <views:SmartForm/>
</Grid>



智能表视图加载一个ItemsControl

the SmartForm view loads an ItemsControl

<Grid Margin="10">
    <ItemsControl
        ItemsSource="{Binding DataTypeViews}"/>
</Grid>



这是DataTypeViews的一个ObservableCollection:

which is an ObservableCollection of DataTypeViews:

List<FormField> formFields = new List<FormField>();
formFields.Add(new FormField { IdCode = "firstName", Label = "First Name", Value = "Jim" });
formFields.Add(new FormField { IdCode = "lastName", Label = "Last Name", Value = "Smith" });
formFields.Add(new FormField { IdCode = "address1", Label = "Address 1", Value = "123 North Ashton Rd." });
formFields.Add(new FormField { IdCode = "address2", Label = "Address 2", Value = "Box 23434" });
formFields.Add(new FormField { IdCode = "city", Label = "City", Value = "New Haven" });
formFields.Add(new FormField { IdCode = "state", Label = "State", Value = "NM" });
formFields.Add(new FormField { IdCode = "zip", Label = "Zip Code", Value = "34234" });

foreach (FormField formField in formFields)
{
    DataTypeView dtv = new DataTypeView();
    DataTypeViewModel dtvm = new DataTypeViewModel(formField);
    dtv.DataContext = dtvm;
    DataTypeViews.Add(dtv);
}

和每个视图显示它建立一个表单标签和文本框:

and each view shows the label and textbox which builds a form:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="90"/>
        <ColumnDefinition Width="400"/>
    </Grid.ColumnDefinitions>
    <StackPanel Orientation="Horizontal" Grid.Column="0">
        <TextBlock Text="{Binding Label}" FontSize="14"/>
        <TextBlock Text=": " FontSize="14"/>
    </StackPanel>
    <TextBox Grid.Column="1" Text="{Binding Value}" FontSize="12"/>
</Grid>



我如何泡这种情况发生在DataTypeViewModel成SmartFormViewModel文本框的变化?

How do I bubble the Textbox changes that happen in DataTypeViewModel up into SmartFormViewModel?

或者换句话说:如果视图模型A包含视图模型b的集合,变化发生在一个视图模型b,我怎么能泡,最多改变视图模型A

推荐答案

您可以只拥有父虚拟机连接到子虚拟机PropertyChanged事件。这是怎样的一个PITA的跟踪已加入谁的孩子/删除诸如此类,所以你可能会改为考虑将你的孩子的VM在我的 ItemObservableCollection

You can just have the parent VM connect to the PropertyChanged event on the child VMs. It's kind of a PITA to keep track of the children who have been added/removed etcetera so you might instead consider storing your child VMs in my ItemObservableCollection:

public sealed class ItemObservableCollection<T> : ObservableCollection<T>
    where T : INotifyPropertyChanged
{
    public event EventHandler<ItemPropertyChangedEventArgs<T>> ItemPropertyChanged;

    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);
        item.PropertyChanged += item_PropertyChanged;
    }

    protected override void RemoveItem(int index)
    {
        var item= this[index];
        base.RemoveItem(index);
        item.PropertyChanged -= item_PropertyChanged;
    }

    protected override void ClearItems()
    {
        foreach (var item in this)
        {
            item.PropertyChanged -= item_PropertyChanged;
        }

        base.ClearItems();
    }

    protected override void SetItem(int index, T item)
    {
        var oldItem = this[index];
        oldItem.PropertyChanged -= item_PropertyChanged;
        base.SetItem(index, item);
        item.PropertyChanged -= item_PropertyChanged;
    }

    private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        OnItemPropertyChanged((T)sender, e.PropertyName);
    }

    private void OnItemPropertyChanged(T item, string propertyName)
    {
        ItemPropertyChanged.Raise(this, new ItemPropertyChangedEventArgs<T>(item, propertyName));
    }
}



那么父虚拟机可以只听所有变更与子项:

Then your parent VM can just listen for all changes to child items with:

_formFields.ItemPropertyChanged += (s, e) => Foo();

这篇关于如何泡在我的ViewModel层次的变化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆