如何解决WPF / MVVM中ObservableCollection的双向绑定和筛选
我正在学习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"/>
...
<Grid.ContextMenu>
<ContextMenu>
...
</ContextMenu>
</Grid.ContextMenu>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
所有这些工作-直到我尝试“发送” <CheckBox IsChecked="{Binding Path=MarkedForUpdate...
回到我的模型之前-它将存储在该模型中。
如何完成? (我可以在ICollectionView
上使用二传手吗?)
可以更改当前架构。我最终需要的是:
- 在
installations
中显示模型中的项目(ListView
)(当前:works
) - 过滤/仅显示符合某些条件的安装(当前为
works
) - 将
MarkedForUpdate
复选框中的更改反映回模型(当前为not working
)
我在Google上搜索了很多,但是找不到相关的解决方案或建议。 任何帮助将不胜感激。谢谢!
解决方法
我发现了问题所在。尽管这是一个愚蠢的错误,但我还是想分享它以节省别人的时间。
模型本身按照上述配置进行更新。问题在于哪个模型属性(在我的情况下为Machine.Installations
)没有实现INotifyPropertyChanged接口,因此其他视图(通过其相应的ViewModel)不知道更改。因此,不仅应该在{strong> ViewModel 中使用OnPropertyChanged/RaisePropertyChanged
,而且还应在 Model 中使用 // Enable TLS 1.1 and 1.2
System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)768 | (System.Net.SecurityProtocolType)3072;
// OR -- Enable JUST TLS 1.2
//System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)3072;
。
希望这可能对某人有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。