C# WPF/MVVM中ObservableCollection的双向绑定和过滤
我正在学习MVVM模式,同时将应用程序重构为MVVM 我有一个模型类C# WPF/MVVM中ObservableCollection的双向绑定和过滤,c#,wpf,mvvm,data-binding,binding,C#,Wpf,Mvvm,Data Binding,Binding,我正在学习MVVM模式,同时将应用程序重构为MVVM 我有一个模型类Machine,它以可观察收集安装的形式提供安装列表 在其中一个窗口(视图)中,我只需要显示那些有更新的安装(因此满足以下条件): 我通过在我的ViewModel中过滤来实现这一点: class NewVersionViewModel : ViewModelBase { private Machine machine = App.Machine; ... public NewVersionViewMod
Machine
,它以可观察收集安装的形式提供安装列表
在其中一个窗口(视图)中,我只需要显示那些有更新的安装(因此满足以下条件):
我通过在我的ViewModel中过滤来实现这一点:
class NewVersionViewModel : ViewModelBase
{
private Machine machine = App.Machine;
...
public NewVersionViewModel(...)
{
...
InstallationsToUpdate.CollectionChanged += (s, e) =>
{
OnPropertyChanged("NewVersionsAvailableMessage");
OnFilterChanged();
};
installationsToUpdateSource = new CollectionViewSource();
installationsToUpdateSource.Source = InstallationsToUpdate;
installationsToUpdateSource.Filter += InstallationsToUpdateFilter;
}
public ObservableCollection<Installation> InstallationsToUpdate
{
get { return machine.Installations; }
set { machine.Installations = value; }
}
internal CollectionViewSource installationsToUpdateSource { get; set; }
public ICollectionView InstallationsToUpdateSourceCollection
{
get { return installationsToUpdateSource.View; }
}
...
}
class NewVersionViewModel:ViewModelBase
{
专用机器=应用程序机器;
...
公共NewVersionViewModel(…)
{
...
InstallationsToUpdate.CollectionChanged+=(s,e)=>
{
OnPropertyChanged(“新版本可用消息”);
OnFilterChanged();
};
installationsToUpdateSource=new CollectionViewSource();
installationsToUpdateSource.Source=InstallationsToUpdate;
installationsToUpdateSource.Filter+=InstallationsToUpdateFilter;
}
公共ObservableCollection安装更新
{
获取{return machine.Installations;}
设置{machine.Installations=value;}
}
内部集合ViewSource安装更新资源{get;set;}
公共ICollectionView安装更新资源集合
{
获取{return installationsToUpdateSource.View;}
}
...
}
这是通过自定义ListView完成的:
<ListView ItemsSource="{Binding InstallationsToUpdateSourceCollection}" ... >
...
<ListView.ItemTemplate>
<DataTemplate>
<Grid ...>
<Grid ...>
<CheckBox Style="{StaticResource LargeCheckBox}"
IsChecked="{Binding Path=MarkedForUpdate, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding Path=HasNewVersion}"
/>
</Grid>
<Label Content="{Binding Path=InstalledVersion.Major}" Grid.Column="1" Grid.Row="0" FontSize="50" FontFamily="Segoe UI Black" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,-10,0,0"/>
...
<Grid.ContextMenu>
<ContextMenu>
...
</ContextMenu>
</Grid.ContextMenu>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
...
...
...
所有这些都有效-直到我尝试“发送”我才发现问题所在。虽然这是一个愚蠢的错误,但我还是想分享它,以节省别人的时间
模型本身在上述配置中更新。问题是什么模型属性(Machine.Installations
在我的例子中)没有实现INotifyPropertyChanged接口,因此其他视图(通过其相应的ViewModels)没有意识到更改。因此,不仅应在视图模型中,而且还应在模型中使用on属性更改/RaisePropertyChanged
希望这能对其他人有所帮助。在WPF中过滤视图的典型方法是使用CollectionViewSorce。试着用它来实现它。
<ListView ItemsSource="{Binding InstallationsToUpdateSourceCollection}" ... >
...
<ListView.ItemTemplate>
<DataTemplate>
<Grid ...>
<Grid ...>
<CheckBox Style="{StaticResource LargeCheckBox}"
IsChecked="{Binding Path=MarkedForUpdate, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding Path=HasNewVersion}"
/>
</Grid>
<Label Content="{Binding Path=InstalledVersion.Major}" Grid.Column="1" Grid.Row="0" FontSize="50" FontFamily="Segoe UI Black" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,-10,0,0"/>
...
<Grid.ContextMenu>
<ContextMenu>
...
</ContextMenu>
</Grid.ContextMenu>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>