WPF绑定集合中所有项的属性我需要绑定的是bool属性,只有当某个属性在收藏是真的。这是绑定:和视图模型:publicclassMainWindowViewModel:INotifyPropertyChanged{privateObservableCollection_tabs;publicObservableCollectionTabs{get{return_tabs;}set{if(value!=_tabs){_tabs=value;NotifyPropertyChanged();}}}Tab类也有属性变化通知:publicobjectConvert(objectvalue,TypetargetType,objectparameter,CultureInfoculture){vartabs=valueasObservableCollection;返回tabs.Any(tab=>tab.IsBusy);问题是,当Tab.IsBusy发生变化时,绑定源不会被通知,因为它绑定到可观察集合而不是IsBusy属性。当IsBusy中任何项目的IsBusy属性发生变化时,有没有办法正确触发通知?您可以在MainWindowViewModel中有一个AnyTabBusy属性,而不是绑定转换器,PropertyChanged事件处理程序会触发更改通知,并且当它们被添加到集合或从集合中删除时,它们将附加或分离到Tabs集合的各个元素。在下面的示例中,Tabs属性是只读的。如果它必须是可写的,则必须在Tabssetter中附加和分离TabsCollectionChanged处理程序。公共类MainWindowViewModel:INotifyPropertyChanged{公共事件PropertyChangedEventHandlerPropertyChanged;公共ObservableCollection标签{get;}=新的ObservableCollection();publicboolAnyTabBusy{get{returnTabs.Any(t=>t.IsBusyubView);Tabs.CollectionChanged+=TabsCollectionChanged;}privatevoidTabsCollectionChanged(objectsender,NotifyCollectionChangedEventArgse){switch(e.Action){caseNotifyCollectionChangedAction.Add:foreach(Tabtabine.NewItems){tab.PropertyChanged+=TabPropertyChanged;}b;caseNotifyCollectionChangedAction.Remove:foreach(e.OldItems中的选项卡){tab.PropertyChanged-=TabPropertyChanged;}休息;默认值:中断;}}privatevoidTabPropertyChanged(objectsender,PropertyChangedEventArgse){if(e.PropertyName==nameof(Tab.IsBusy)){PropertyChanged?.Invoke(this,newPropertyChangedEventArgs(nameof(AnyTabBusy)));如果你想让这段代码可以重用,你可以把它放在派生的集合类中,如下所示您可以在其中附加ItemPropertyChanged事件的处理程序公共类ObservableItemCollection:ObservableCollection其中T:INotifyPropertyChanged{公共事件PropertyChangedEventHandlerItemPropertyChanged;protectedoverridevoidOnCollectionChanged(NotifyCollectionChangedEventArgse){base.OnCollectionChanged(e);switch(e.Action){caseNotifyCollectionChangedAction.Add:foreach(INotifyPropertyChangeditemine.NewItems){item.PropertyChanged+=OnItemPropertyChanged;}休息;caseNotifyCollectionChangedAction.Remove:foreach(INotifyPropertyChangeditemine.OldItems){item.PropertyChanged-=OnItemPropertyChanged;}休息;默认值:中断;}}privatevoidOnItemPropertyChanged(objectsender,PropertyChangedEventArgse){ItemPropertyChanged?.Invoke(this,e);}}视图模型现在可以简单化为:publicclassMainWindowViewModel:INotifyPropertyChanged{publiceventPropertyChangedEventHandlerPropertyChanged;公共ObservableItemCollection标签{get;}=新的ObservableItemCollection();公共布尔AnyTabBusy{get{返回Tabs.Any(t=>t.IsBusy);}}publicMainWindowViewModel(){Tabs.ItemPropertyChanged+=TabPropertyChanged;}privatevoidTabPropertyChanged(objectsender,PropertyChangedEventArgse){if(e.PropertyName==nameof(Tab.IsBusy)){PropertyChanged?.Invoke(this,newPropertyChangedEventArgs(nameof(AnyTabBusy)));我已经接受了@Clemens的回答并转换为一种扩展方法,该方法可以更轻松地用于多个集合中使用它将采用PropertyChangedEventHandler并在从集合中添加和删除项目时自动添加和删除它。如果您对此投票,请也为@Clemens投票,因为这是基于他的工作。小心不要在未采取特殊预防措施的情况下将匿名方法用作PropertyChanged处理程序(这适用于所有事件处理程序,而不仅仅是此解决方案),因为它们很难删除。(注意:这需要C#7,因为它使用本机函数来更轻松地处理CollectionChanged处理程序的委托。)publicstaticclassObservableCollectionExtensions{publicstaticHookRegisterPropertyChangeHook(thisObservableCollectioncollection,PropertyChangedEventHandlerhandler)whereTList:INotifyPropertyChanged{voidCollection_CollectionChanged(objectsender,NotifyCollectionChangedEventArgse){switch(e.Action){caseNotifyCollectionChangedAction.Add:foreach(TList项目在e.NewItems){item.PropertyChanged+=handler;}休息;caseNotifyCollectionChangedAction.Remove:foreach(TListitemine.OldItems){item.PropertyChanged-=handler;}}休息;默认值:中断;}}返回新钩子(集合,Collection_CollectionChanged);}publicclassHookwhereTList:INotifyPropertyChanged{internalHook(ObservableCollectioncollection,NotifyCollectionChangedEventHandlerhandler){_handler=handler;_collection=集合;collection.CollectionChanged+=处理程序;私人NotifyCollectionChangedEventHandler_handler;私有ObservableCol集合_集合;publicvoidUnregister(){_collection.CollectionChanged-=_handler;你可以像这样使用它:voidMain(){varlist=newObservableCollection();list.RegisterPropertyChangeHook(OnPropertyChange);变种动物=新动物();//有一个引发PropertyChangedlist.Add(animal)的“Name”属性;animal.Name="查理";//OnPropertyChange调用list.Remove(animal);动物名称=“山姆”;//OnPropertyChange没有调用}privatevoidOnPropertyChange(objectsender,PropertyChangedEventArgse){Console.WriteLine($"propertychanged:{e.PropertyName}");如果你想取消注册钩子:varhook=list.RegisterPropertyChangeHook(OnPropertyChange);钩子。取消注册();由于扩展方法类不支持泛型,注销最终比我预期的要棘手它使用“备忘录”模式返回一个可用于稍后注销的对象。要将通知从模型传播到模型集合,您需要在集合本身上具有Notifiable属性。也许您可以扩展ObservableCollection并在其中拥有一个可以通知UI的属性不幸的是,没有办法免费获得它。我会在MainWindowViewModel上创建一个IsBusy属性。设置选项卡后,为集合更改添加侦听器并让它更新IsBusy属性。以上是C#学习教程:WPF绑定集合中所有项的属性共享的所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
