I think it may be quite simple but I have been googling a solution for a while without success, and I am not sure what is the correct approach. I saw that Prism could be a solution but I am looking for something simple.
I have a MainViewModel and a MainView which contains a Datagrid. The MainView contains also a ContentControl which display a ChildView (with DataContext as ChildViewModel).
I use DataTemplate to associate Views and ViewModels.
The DataGrid of the MainView is Binded to an ObservableCollection of the ChildViewModel.
I want this DataGrid to be updated every time this Collection is modified. I have tried to use the INotifyPropertyChanged. I have tried to use the OnCollectionChanged.
When I debug I can see that the Collection has changed and that event is fired but how to refresh the binding ? (dataGrid is not updated).
Here is the code:
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());
}`
Edit @lezhkin11
Yes I think that is the problem. But I have no idea how to fix it
Code behind MainView
void MainView_Loaded(object sender, RoutedEventArgs e)
{
mainViewModel = new MainViewModel();
DataContext = mainViewModel;
}
Code behind ChildView
void ChildView_Loaded(object sender, RoutedEventArgs e)
{
childViewModel = new ChildViewModel();
DataContext = childViewModel;
}
A button allow to do a new search:
private void BtnRefresf_Click(object sender, RoutedEventArgs e) // Search
{
childViewModel.Search();
}
Then a method in the childViewModel will use the service to give a new value to the Observable collection (when I debug, I can reach the OnpropertyChanged of the collection)
public void Search()
{
ObservableCollection<Child> collec = new ObservableCollection<Child>(ChildService.GetAllChild());
Children = collec;
}
ChildView_Loaded
and in DataTemplate do<vi:ChildView DataContext="{Binding}" />
. 2) removepublic ChildViewModel childViewModel { get; set; }
then removeContentControl
andDataTemplate
. Your new XAML<vi:ChildView x:Name="MyChild" /> <DataGrid ItemsSource="{Binding DataContext.Children, ElementName=MyChild,Mode=TwoWay}"
– lezhkin11x:Name="MyChild"
. – lezhkin11