WPF MVVM-从子视图模型更新MainView的Datagrid

时间:2018-08-12 06:01:52

标签: c# wpf mvvm datagrid

我认为这可能非常简单,但是我一直在寻找解决方案一段时间,但没有成功,而且我不确定什么是正确的方法。我看到Prism可能是一个解决方案,但我正在寻找简单的方法。

我有一个MainViewModel和一个包含Datagrid的MainView。 MainView还包含一个ContentControl,它显示一个ChildView(DataContext作为ChildViewModel)。

我使用DataTemplate关联视图和ViewModel。

MainView的DataGrid绑定到ChildViewModel的ObservableCollection。

我希望每次修改此Collection时都更新此DataGrid。 我试图使用INotifyPropertyChanged。 我试图使用OnCollectionChanged。

当我调试时,可以看到Collection发生了更改,并且该事件被触发,但是如何刷新绑定? (dataGrid未更新)。

代码如下:

DataTemplate

<DataTemplate DataType="{x:Type vm:ChildViewModel}">
    <vi:ChildView />
</DataTemplate>

XAML MainView

     <ContentControl Content="{Binding childViewModel}"/>

     <DataGrid x:Name="DataGridChildren"
                       ItemsSource="{Binding childViewModel.Children,Mode=TwoWay}" 
                       SelectedItem="{Binding childViewModel.SelectedItem}" EnableRowVirtualization="True" IsReadOnly="True" AutoGeneratingColumn="DataGrid_AutoGeneratingColumn">

MainViewModel

public ChildViewModel childViewModel { get; set; }

public MainViewModel()
{
    childViewModel = new ChildViewModel();
}

ViewModelBase

public abstract class ViewModelBase : INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }

        protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, args);
        }
    }

ChildViewModel

 public class ChildViewModel: ViewModelBase
    {
        private ObservableCollection<Child> _Children;
        public ObservableCollection<Child> Children
        {
            get { return _Children; }
            set
            {
                _Children = value;
                OnPropertyChanged("Children");
                _Children.CollectionChanged +=handler;   
            }
        }

        private void handler(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            //What to do ?
        }

        public ChildViewModel()
        {
            Children = new ObservableCollection<Child>(ChildService.GetAllChild());
        }`    

编辑@ lezhkin11

是的,我认为这是问题所在。但我不知道如何解决

MainView后面的代码

void MainView_Loaded(object sender, RoutedEventArgs e)
{  
    mainViewModel = new MainViewModel();
    DataContext = mainViewModel;
}

ChildView后面的代码

void ChildView_Loaded(object sender, RoutedEventArgs e)
{
     childViewModel = new ChildViewModel();
     DataContext = childViewModel;
}

一个按钮允许进行新的搜索:

 private void BtnRefresf_Click(object sender, RoutedEventArgs e) // Search
 {
      childViewModel.Search();
 }

然后childViewModel中的方法将使用该服务为Observable集合赋予新值(当我调试时,我可以到达该集合的OnpropertyChanged)

   public void Search()
     {
            ObservableCollection<Child> collec = new ObservableCollection<Child>(ChildService.GetAllChild());

            Children = collec;
    }

1 个答案:

答案 0 :(得分:0)

您的DataGrid绑定到ChildViewModel内部的MainViewModel(实例1)。 ChildView拥有自己的ChildViewModel(实例2)。

您必须确保两个控件都引用同一实例。

1)从MainViewModel中完全删除public ChildViewModel childViewModel { get; set; }

2)给ChildView命名。

<vi:ChildView x:Name="MyChild" />

3)绑定DataGrid的属性以更正视图模型

 <DataGrid ItemsSource="{Binding DataContext.Children, ElementName=MyChild, Mode=TwoWay}" />

此外,我建议直接在构造函数中初始化DataContext。 加载事件为时已晚-结果您总是会有很多XAML绑定异常会影响性能(甚至可能导致意外行为)