我的问题是,只有在更改GroupDescription值时才更新分组,而只有在列表视图源中项目的bound属性更改后才会更新.
在下面的示例中,GroupDescription设置为city,从而产生“City:Hamburg”的组描述.但是当更改项目城市属性时,列表视图中的分组不会更新,这意味着在“城市:汉堡”组中将有一个城市“柏林”的项目.
只有在更新GroupDescription后才会更新分组.我试图找到一个使用PersonPropertyChanged方法的工作,该方法将GroupDescription更改为PersonID并立即返回City.然而,如果滚动位置例如在列表视图的中间或末尾,则此工作导致列表视图总是跳回到顶部.当使用包含具有更改属性的条目的列表视图时,这可能非常烦人.
有没有一种方法可以在项目属性更改后“更新”分组,而不会将列表视图跳回到顶部?
预先感谢您的任何帮助!
托马斯
GrouPingListVIEw.cs
using System.windows.Controls;using System.windows;using System.windows.Data;namespace WpfApplication{ /// <summary> /// Enhanced List vIEw based on WPF ListVIEw with dependency propertIEs for GroupDescriptions /// </summary> public class GrouPingListVIEw : ListVIEw { /// <summary> /// Dependency property for group descriptions /// </summary> public string GroupDescription { get { return (string)GetValue(GroupDescriptionProperty); } set { SetValue(GroupDescriptionProperty,value); } } /// <summary> /// Using a DependencyProperty as the backing store for GroupDescription. This enables animation,styling,binding,etc... /// </summary> public static Readonly DependencyProperty GroupDescriptionProperty = DependencyProperty.Register("GroupDescription",typeof(string),typeof(GrouPingListVIEw),new UIPropertyMetadata(string.Empty,GroupDescriptionChanged)); private static voID GroupDescriptionChanged(DependencyObject source,DependencyPropertyChangedEventArgs args) { var control = source as GrouPingListVIEw; // Stop if source is not of type DetailedListVIEw if (control == null) return; // Stop if myVIEw is not available,myVIEw can not group,groupdescription missing\ // or the argument is empty var myVIEw = (CollectionVIEw)CollectionVIEwSource.Getdefaultview(control.ItemsSource); if (myVIEw == null || !myVIEw.Cangroup || (string) args.NewValue == string.Empty || myVIEw.GroupDescriptions == null) { return; } myVIEw.GroupDescriptions.Clear(); // If a group description already if(myVIEw.GroupDescriptions.Count > 0) { var prop = myVIEw.GroupDescriptions[0] as PropertyGroupDescription; if(prop != null) { if(!prop.Propertyname.Equals((string)args.NewValue)) { myVIEw.GroupDescriptions.Clear(); } } } // Stop if at this point a group description still exists. This means the newValue is // equal to the old value and nothing needs to be changed if (myVIEw.GroupDescriptions.Count != 0) return; // If this code is reached newValue is different than the current groupDescription value // therefore the newValue has to be added as PropertyGroupDescription var groupDescription = new PropertyGroupDescription((string)args.NewValue); // Clear and add the description only if it's not already existing myVIEw.GroupDescriptions.Add(groupDescription); } }}
MainWindow.xaml
<Window x:Class="WpfApplication.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfApplication="clr-namespace:WpfApplication" title="MainWindow" Height="300" WIDth="300"> <StackPanel> <button Content="Change" Click="btnChangeCity" Height="22"/><button Content="Change back" Click="btnChangeCityBack" Height="22"/> <WpfApplication:GrouPingListVIEw ItemsSource="{Binding Persons}" Height="200" GroupDescription="{Binding GroupDescription}" x:name="GrouPingListVIEw"> <ListVIEw.GroupStyle> <GroupStyle> <GroupStyle.headerTemplate> <DataTemplate> <GrID HorizontalAlignment="Stretch"> <border HorizontalAlignment="Stretch" borderBrush="transparent" borderThickness="1" CornerRadius="3"> <border HorizontalAlignment="Stretch" borderBrush="lightGray" borderThickness="0,1" CornerRadius="0"> <StackPanel OrIEntation="Horizontal"> <TextBlock Foreground="lightGray" Text="{Binding GroupDescription,Elementname=GrouPingListVIEw}"/> <TextBlock Foreground="lightGray" Text=" : "/> <TextBlock Foreground="lightGray" Text="{Binding name}" HorizontalAlignment="Stretch"/> </StackPanel> </border> </border> </GrID> </DataTemplate> </GroupStyle.headerTemplate> </GroupStyle> </ListVIEw.GroupStyle> <ListVIEw.VIEw> <GrIDVIEw> <GrIDVIEwColumn header="PersonID" WIDth="100"> <GrIDVIEwColumn.CellTemplate> <DataTemplate> <TextBlock TextTrimming="CharacterEllipsis" Text="{Binding PersonID,Mode=Default}"/> </DataTemplate> </GrIDVIEwColumn.CellTemplate> </GrIDVIEwColumn> <GrIDVIEwColumn header="City" WIDth="100"> <GrIDVIEwColumn.CellTemplate> <DataTemplate> <TextBlock TextTrimming="CharacterEllipsis" Text="{Binding City,Mode=Default}"/> </DataTemplate> </GrIDVIEwColumn.CellTemplate> </GrIDVIEwColumn> </GrIDVIEw> </ListVIEw.VIEw> </WpfApplication:GrouPingListVIEw> </StackPanel></Window>
MainWindow.xaml.cs
using System.Collections.ObjectModel;using System.Collections.Specialized;using System.ComponentModel;namespace WpfApplication{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : INotifyPropertyChanged { public class Person : INotifyPropertyChanged { public Person(string personID,string city) { PersonID = personID; City = city; } private string _personID; private string _city; public event PropertyChangedEventHandler PropertyChanged; protected voID OnPropertyChanged(string name) { PropertyChangedEventHandler pc = PropertyChanged; if (pc != null) pc(this,new PropertyChangedEventArgs(name)); } public string PersonID { get { return _personID; } set { _personID = value; OnPropertyChanged("PersonID"); } } public string City { get { return _city; } set { _city = value; OnPropertyChanged("City"); } } } public ObservableCollection<Person> Persons { get; set; } public string GroupDescription { get { return _groupDescription; } set { _groupDescription = value; OnPropertyChanged("GroupDescription"); } } private string _groupDescription; public MainWindow() { InitializeComponent(); DataContext = this; GroupDescription = "City"; Persons = new ObservableCollection<Person>(); Persons.CollectionChanged += PersonsCollectionChanged; Persons.Add(new Person("1","Hamburg")); Persons.Add(new Person("2","Hamburg")); Persons.Add(new Person("3","Hamburg")); Persons.Add(new Person("4","Hamburg")); Persons.Add(new Person("5","Hamburg")); Persons.Add(new Person("6","Hamburg")); Persons.Add(new Person("7","Hamburg")); Persons.Add(new Person("8","Hamburg")); Persons.Add(new Person("9","Berlin")); Persons.Add(new Person("10","Hamburg")); Persons.Add(new Person("11","Hamburg")); Persons.Add(new Person("12","Munich")); Persons.Add(new Person("13","Munich")); OnPropertyChanged("Persons"); } public voID PersonsCollectionChanged(object sender,NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Remove) { foreach(Person item in e.oldItems) { //Removed items item.PropertyChanged -= PersonPropertyChanged; } } else if (e.Action == NotifyCollectionChangedAction.Add) { foreach(Person item in e.NewItems) { //Added items item.PropertyChanged += PersonPropertyChanged; } } } public voID PersonPropertyChanged(object sender,PropertyChangedEventArgs e) { //GroupDescription = "PersonID"; //GroupDescription = "City"; } public event PropertyChangedEventHandler PropertyChanged; protected voID OnPropertyChanged(string name) { PropertyChangedEventHandler pc = PropertyChanged; if (pc != null) pc(this,new PropertyChangedEventArgs(name)); } private voID btnChangeCity(object sender,System.windows.RoutedEventArgs e) { Persons[0].City = "Berlin"; } private voID btnChangeCityBack(object sender,System.windows.RoutedEventArgs e) { Persons[0].City = "Hamburg"; } }}解决方法 我意识到现在已经很晚了,但是如果你使用的是.NET4.5或更高版本,你可以使用实时分组功能,我认为它可以完全按照你的需要进行 *** 作.
例如,不是将ListVIEw ItemsSource直接绑定到Persons,而是绑定到一个CollectionVIEwSource,它本身绑定到Persons:
<Window.Resources> <CollectionVIEwSource x:Key="PersonsVIEwSource" Source="{Binding Persons}" IsliveGrouPingRequested="True"> <CollectionVIEwSource.GroupDescriptions> <PropertyGroupDescription Propertyname="Groupname" /> </CollectionVIEwSource.GroupDescriptions> </CollectionVIEwSource></Window.Resources>
如上所示,您只需添加属性IsliveGrouPingRequested =“True”,并添加要重新组合的属性名称.
当Groupname属性更改时(通过使用INotifyPropertyChanged),相关项将自动移动到ListVIEw中的正确组,而不更改任何其他内容.
总结以上是内存溢出为你收集整理的c# – 更改绑定属性时,ListView分组不会更新全部内容,希望文章能够帮你解决c# – 更改绑定属性时,ListView分组不会更新所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)