I am using the MVVM pattern and in my view I have this dataGrid
:
<Setter Property="Background">
<Setter.Value>
<MultiBinding Converter="{StaticResource myMultiValueConverter}">
<MultiBinding.Bindings>
<Binding />
<Binding ElementName="ThisControl" Path="DataContext.MyObservableCollectionInViewModel"/>
<Binding ElementName="thisControl" Path="DataContext.ControlType"/>
<Binding ElementName="ThisControl" Path="DataContext.ExternalItems"/>
<Binding Path="Componentes.OneProperty"/>
</MultiBinding.Bindings>
</MultiBinding>
</Setter.Value>
</Setter>
And my view model has this code:
private void myMethod()
{
MyObservableCollectionInViewModel.Clear();
MyObservableCollectionViewModel.Add(new myType());
}
When I execute the method MyMethod()
, if a I am not wrong, the multi value converter would be run, because the ObservableCollection
implements INotifyPropertyChanged
when I add or remove items, but in this case does not work.
However I have another ObservableCollection
for the DataSource
of my dataGrid
and it works as it's expected, refresh the dataGrid
when I add or remove items from the ObservableCollection
.
However, if in myMethod
I do this:
private myMethod()
{
myObservableCollectionInMyViewModel.Clear();
myObservableCollectionInMyViewModel.Add(new MyType());
myObservableCollectionInMyViewModel = new ObservableCollection(myObservableCollectionInMyViewModel);
}
It works, so the view is notified when I create a new ObservableCollection
, not when I add or remove items from the actual ObservableCollecion
.
Yes, that's the correct behavior.
The reason the
ObservableCollection
Add/Remove works forItemsControl
,ListBox
,DataGrid
etc, is that they are explictly taking care of the behavior you are describing, that is not WPF specific, eg: it doesn't have to do with the actual binding ofItemsSource
.What happens under the cover is, all these controls(
ListBox
, etc..) are inheriting fromItemsControl
which ultimately wrapsItemsSource
intoCollectionView
, which will take advantange ofINotifyCollectionChanged
interface, if possible. That's how it knows / keeps up.The "work-around" I've used successfully:
A) Just use property changed or do the swap as you've done (this might, or might not work - I don't exactly remember, but WPF might have explicit check if the actual value has been changed, in this case: it hasn't):
B)
C) Bind against .Count, as
ObservableCollection
will notify when that changes.D) Create a new converter which will be able to listen all the events(INotifyPropertyChanged and INotifyCollectionChanged) events, which then will trigger multi converter updates.