我如何知道ListBoxItem是否是Wpf中ListBox中的最后一项?我怎么知道ListBoxItem是Wpf的ListBox集合的最后一项(在ItemContainerStyle或ItemContainer的模板中)?这个问题是因为我需要知道一个项目是否是最后一个以其他方式显示它的项目。例如:假设我想显示用分号分隔的项目,但最后一项:a;b;c这在html和ccs中使用ccs选择器很容易做到。但是,我怎样才能在Wpf中做到这一点?由于将“索引”附加属性实现到ListBoxItem以完成正确的工作似乎相当困难,我相信更简单的方法是在MVVM中。您可以将必要的逻辑(“IsLast”属性等)添加到列表的实体类型,并让ViewModel处理此更新,在修改或替换集合时更新它。编辑经过一番尝试,我设法使用附加属性的混合和inheritListBox来实现ListBoxItems的索引(并因此在最后检查)。看这个:publicclassIndexedListBox:System.Windows.Controls.ListBox{publicstaticintGetIndex(DependencyObjectobj){return(int)obj.GetValue(IndexProperty);}publicstaticvoidSetIndex(DependencyObjectobj,intvalue){obj.SetValue(IndexProperty,value);}//////跟踪ListBoxItem的索引///publicstaticreadonlyDependencyPropertyIndexProperty=DependencyProperty.RegisterAttached("Index",typeof(int),typeof(IndexedListBox),newUIPropertyMetadata(0));publicstaticboolGetIsLast(DependencyObjectobj){return(bool)obj.GetValue(IsLastProperty);}publicstaticvoidSetIsLast(DependencyObjectobj,boolvalue){obj.SetValue(IsLastProperty,value);}//////通知ListBoxItem是否是集合中的最后一个。///publicstaticreadonlyDependencyPropertyIsLastProperty=DependencyProperty.RegisterAttached("IsLast",typeof(bool),typeof(IndexedListBox),newUIPropertyMetadata(false));受保护的覆盖voidOnItemsSourceChanged(System.Collections.IEnumerableoldValue,System.Collections.IEnumerablenewValue){//我们捕获ItemsSourceChanged以检查新的是否可修改,因此我们可以对其更改做出反应。varoldSource=oldValueasINotifyCollectionChanged;如果(oldSource!=null)oldSource.CollectionChanged-=ItemsSource_CollectionChanged;varnewSource=newValueasINotifyCollectionChanged;如果(newSource!=null)newSource.CollectionChanged+=ItemsSource_CollectionChanged;base.OnItemsSourceChanged(oldValue,newValue);}voidItemsSource_CollectionChanged(objectsender,NotifyCollectionChangedEventArgse){this.ReindexItems();}protectedoverridevoidPrepareContainerForItemOverride(System.Windows.DependencyObjectelement,objectitem){//我们在生成ItemContainer时设置索引和其他相关属性varindex=this.Items.IndexOf(item);SetIsLast(元素,索引==this.Items.Count-1);设置索引(元素,索引);base.PrepareContainerForItemOverride(元素,项目);}privatevoidReindexItems(){//如果集合被修改,可能需要重新索引所有ListBoxItems。foreach(variteminthis.Items){varitemContainer=this.ItemContainerGenerator.ContainerFromItem(item);如果(itemContainer==null)继续;intindex=this.Items.IndexOf(item);SetIsLast(itemContainer,index==this.Items.Count-1);SetIndex(itemContainer,索引);}}}为了测试它,我们设置了一个简单的ViewModel和一个Item类:publicclassViewModel:INotifyPropertyChanged{#regionINotifyPropertyChangedprotectedvoidOnPropertyChanged(stringpropertyName){if(this.PropertyChanged!=null){this.PropertyChanged(this,newPropertyChangedEventArgs(propertyName));}}#endregion私有ObservableCollection项目;publicObservableCollectionItems{get{returnthis.items;}set{if(this.items!=value){this.items=value;这个.OnPropertyChanged("项目");}}}publicViewModel(){this.InitItems(20);}publicvoidInitItems(intcount){this.Items=newObservableCollection();for(inti=0;iView:在代码隐藏视图中,我放置了一些逻辑来测试集合更新时解决方案的行为:publicpartialclassMainWindow:Window{publicViewModelViewModel{get{returnthis.DataContextasViewModel;}}publicMainWindow(){InitializeComponent();}privatevoidButton_Click(objectsender,RoutedEventArgse){this.ViewModel.Items.Insert(5,newItem(){MyProperty="NewElement"});}privatevoidButton_Click_1(对象发送者,RoutedEventArgse){this.ViewModel.Items.RemoveAt(5);}privatevoidButton_Click_2(对象发送者,RoutedEventArgse){this.ViewModel.InitItems(newRandom()。Next(10,30));}}这个解决方案可以处理静态列表以及ObservableCollections和添加,删除,插入项目希望你觉得它有用。编辑以使用CollectionViews测试它并且它工作正常。在第一个测试中我更改了ListBox中的Sort/GroupDescriptions。项目。当其中之一发生更改时,ListBox会重新创建容器,然后PrepareContainerForItemOverride命中。当它在ListBox.Items本身中查找正确的索引时,顺序会正确更新。第二,我将Items属性设为ViewModel中的ListCollectionView。在这种情况下,当描述更改时,将引发CollectionChanged并且ListBox会按预期进行响应。以上就是C#学习教程:如何知道ListBoxItem是否是Wpf的ListBox中的最后一项?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
