【发布时间】:2020-12-04 14:18:56
【问题描述】:
我在将应用程序重构为 MVVM 时正在学习 MVVM 模式。
我有一个模型类Machine,它以ObservableCollection<Installation> Installations 的形式提供安装列表。
在其中一个窗口(视图)中,我只需要显示那些有更新的安装(因此满足以下条件):
private void InstallationsToUpdateFilter(object sender, FilterEventArgs e)
{
var x = (Installation)e.Item;
bool hasNewVersion = ShowAllEnabledInstallations ? true : x.NewVersion != null;
bool isSetAndOn = !String.IsNullOrEmpty(x.Path) && x.CheckForUpdatesFlag;
e.Accepted = isSetAndOn && hasNewVersion;
}
private void OnFilterChanged()
{
installationsToUpdateSource?.View?.Refresh();
}
我通过在我的 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; }
}
...
}
这是由自定义 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>
所有这些都有效——直到我尝试将<CheckBox IsChecked="{Binding Path=MarkedForUpdate...“发送”回我的模型——所以它将被存储在那里。
如何做到这一点? (我可以在ICollectionView 上设置某种二传手吗?)
可以更改当前架构。我最终需要什么:
- 在
ListView(当前:works)中显示模型中的项目(installations) - 仅过滤/显示满足某些条件的安装(当前:
works) - 将
MarkedForUpdate复选框中的更改反映回模型(当前:not working)
我搜索了很多,但找不到相关的解决方案或建议。 任何帮助将不胜感激。谢谢!
【问题讨论】:
-
在 WPF 中过滤视图的典型方法是使用 CollectionViewSorce。尝试使用它来实现它。
标签: c# wpf mvvm data-binding binding