c# – 更改绑定属性时,ListView分组不会更新

c# – 更改绑定属性时,ListView分组不会更新,第1张

概述我正在使用依赖项属性GroupDescription根据列表视图项源的属性对 WPF列表视图中的项目进行分组. 我的问题是,只有在更改GroupDescription值时才更新分组,而只有在列表视图源中项目的bound属性更改后才会更新. 在下面的示例中,GroupDescription设置为city,从而产生“City:Hamburg”的组描述.但是当更改项目城市属性时,列表视图中的分组不会更新 我正在使用依赖项属性GroupDescription根据列表视图项源的属性对 WPF列表视图中的项目进行分组.

我的问题是,只有在更改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分组不会更新所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1225410.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存