c# – 为什么DataGridRow IsSelected绑定不能在DataGrid上运行

c# – 为什么DataGridRow IsSelected绑定不能在DataGrid上运行,第1张

概述在Josh Smith的MVVM演示中,他使用了ListViewItem样式的ListView,如下所示: <Style x:Key="CustomerItemStyle" TargetType="{x:Type ListViewItem}"> <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWa 在Josh Smith的MVVM演示中,他使用了ListVIEwItem样式的ListVIEw,如下所示:
<Style x:Key="CustomerItemStyle" targettype="{x:Type ListVIEwItem}">    <Setter Property="IsSelected" Value="{Binding Path=IsSelected,Mode=TwoWay}" />    <Style.Triggers>        <MultiTrigger>            <MultiTrigger.Conditions>                <Condition Property="ItemsControl.AlternationIndex" Value="1" />                <Condition Property="IsSelected" Value="False" />                <Condition Property="IsMouSEOver" Value="False" />            </MultiTrigger.Conditions>            <Setter Property="Background" Value="#EEEEEEEE" />        </MultiTrigger>    </Style.Triggers></Style>

它很好地绑定了IsSelected属性.样式应用于ListVIEw,如下所示:

<ListVIEw    ItemContainerStyle="{StaticResource CustomerItemStyle}"  ItemsSource="{Binding}"  >

我的版本

我尝试通过DataGrIDRow以类似的方式与DataGrID绑定IsSelected.但是,当通过项目viewmodel的集合选择项目时会导致问题,其中定义了IsSelected属性.

因为它使用双向绑定,我会认为可以通过UI和项目viewmodel的集合来选择项目.

假设我通过UI选择项目,这很好用.我可以选择单个项目,然后使用[shift]选择范围,然后使用[ctrl]选择更多项目.取消选择项也可以正常工作.

但是我通过集合选择了一堆.让我们说点击按钮(就像我在下面的代码中所做的那样),选择了一堆项目.当我向下滚动DataGrID时,会选择一些,因为它们应该是一些不是.如果我通过UI选择一个项目,那么只有一些项目被取消选择而一些项目仍然被选中,这一切都有点时髦.即使左上角的全选按钮也不是很正确.


所有代码都在下面,底部是视图,关键部分是带有IsSelected绑定的DataGrIDRow样式.

这是我的用户类:

using System.ComponentModel;namespace WpfAppDataGrID.Model{    public class User : INotifyPropertyChanged    {        public static User CreateNewUser()        {            return new User();        }        public User() { }        public int User_ID { get; set; }        public string Username { get; set; }        public string name { get; set; }        public string Job_Title { get; set; }        public string Department { get; set; }        public string Company { get; set; }        public string Phone_Office { get; set; }        public string Phone_Mobile { get; set; }        public string Email { get; set; }        public event PropertyChangedEventHandler PropertyChanged;        private voID RaisePropertyChanged(string propertyname)        {            if (PropertyChanged != null)                PropertyChanged(this,new System.ComponentModel.PropertyChangedEventArgs(propertyname));        }    }}

这是Userviewmodel,其中IsSelected驻留在:

using System;using System.ComponentModel;using WpfAppDataGrID.DataAccess;using WpfAppDataGrID.Model;namespace WpfAppDataGrID.viewmodel{    class Userviewmodel : INotifyPropertyChanged    {        Readonly User _user;        Readonly UserRepository _userRepository;        bool _isSelected;        public Userviewmodel(User user,UserRepository userRepository)        {            if (user == null)                throw new ArgumentNullException("user");            if (userRepository == null)                throw new ArgumentNullException("userRepository");            _user = user;            _userRepository = userRepository;        }        public Userviewmodel()        {        }        public int User_ID        {            get { return _user.User_ID; }            set            {                if (value == _user.User_ID)                    return;                _user.User_ID = value;                RaisePropertyChanged("User_ID");            }        }        public string Username        {            get { return _user.Username; }            set            {                if (value == _user.Username)                    return;                _user.Username = value;                RaisePropertyChanged("Username");            }        }        public string name        {            get { return _user.name; }            set            {                if (value == _user.name)                    return;                _user.name = value;                RaisePropertyChanged("name");            }        }        public string Job_Title        {            get { return _user.Job_Title; }            set            {                if (value == _user.Job_Title)                    return;                _user.Job_Title = value;                RaisePropertyChanged("Job_Title");            }        }        public string Department        {            get { return _user.Department; }            set            {                if (value == _user.Department)                    return;                _user.Department = value;                RaisePropertyChanged("Department");            }        }        public string Company        {            get { return _user.Company; }            set            {                if (value == _user.Company)                    return;                _user.Company = value;                RaisePropertyChanged("Company");            }        }        public string Phone_Office        {            get { return _user.Phone_Office; }            set            {                if (value == _user.Phone_Office)                    return;                _user.Phone_Office = value;                RaisePropertyChanged("Phone_Office");            }        }        public string Phone_Mobile        {            get { return _user.Phone_Mobile; }            set            {                if (value == _user.Phone_Mobile)                    return;                _user.Phone_Mobile = value;                RaisePropertyChanged("Phone_Mobile");            }        }        public string Email        {            get { return _user.Email; }            set            {                if (value == _user.Email)                    return;                _user.Email = value;                RaisePropertyChanged("Email");            }        }        /// <summary>        /// Gets/sets whether this customer is selected in the UI.        /// </summary>        public bool IsSelected        {            get { return _isSelected; }            set            {                if (value == _isSelected)                    return;                _isSelected = value;                RaisePropertyChanged("IsSelected");            }        }        public event PropertyChangedEventHandler PropertyChanged;        private voID RaisePropertyChanged(string propertyname)        {            if (PropertyChanged != null)                PropertyChanged(this,new System.ComponentModel.PropertyChangedEventArgs(propertyname));        }    }}

这是我的AllUsersviewmodel:

using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Collections.Specialized;using System.ComponentModel;using System.Diagnostics;using System.linq;using System.Text;using System.Threading.Tasks;using System.windows.Data;using System.windows.input;using WpfAppDataGrID.DataAccess;namespace WpfAppDataGrID.viewmodel{    class AllUsersviewmodel : INotifyPropertyChanged    {        Readonly UserRepository _userRepository;        public AllUsersviewmodel()        {            _userRepository = new UserRepository();            _userRepository.LoadUsers();            CreateallUsers();        }        voID CreateallUsers()        {            List<Userviewmodel> all =                (from usr in _userRepository.GetUsers()                 select new Userviewmodel(usr,_userRepository)).ToList();            foreach (Userviewmodel uvm in all)            {                uvm.PropertyChanged += this.OnUserviewmodelPropertyChanged;            }            this.UserCollection = new ObservableCollection<Userviewmodel>(all);            this.UserCollection.CollectionChanged += this.OnCollectionChanged;        }        private ObservableCollection<Userviewmodel> userCollection;        public ObservableCollection<Userviewmodel> UserCollection        {            get            {                return userCollection;            }            set            {                userCollection = value;                RaisePropertyChanged("UserCollection");            }        }        RelayCommand selectItemsCommand;        public ICommand SelectItemsCommand        {            get            {                if (selectItemsCommand == null)                    selectItemsCommand = new RelayCommand(SelectItemsCommandExecute,CanSelectItemsCommand);                return selectItemsCommand;            }        }        private voID SelectItemsCommandExecute(object parameter)        {            for (int i = 4; i <= 49; i++)            {                UserCollection[i].IsSelected = true;            }        }        private bool CanSelectItemsCommand(object parameter)        {            return true;        }        voID OnCollectionChanged(object sender,NotifyCollectionChangedEventArgs e)        {            if (e.NewItems != null && e.NewItems.Count != 0)                foreach (Userviewmodel userVM in e.NewItems)                    userVM.PropertyChanged += this.OnUserviewmodelPropertyChanged;            if (e.oldItems != null && e.oldItems.Count != 0)                foreach (Userviewmodel userVM in e.oldItems)                    userVM.PropertyChanged -= this.OnUserviewmodelPropertyChanged;        }        voID OnUserviewmodelPropertyChanged(object sender,PropertyChangedEventArgs e)        {            string IsSelected = "IsSelected";            if (e.Propertyname == IsSelected)                this.RaisePropertyChanged("TotalSelectedUsers");        }        public event PropertyChangedEventHandler PropertyChanged;        private voID RaisePropertyChanged(string propertyname)        {            if (PropertyChanged != null)            {                PropertyChanged(this,new System.ComponentModel.PropertyChangedEventArgs(propertyname));            }        }    }    public class RelayCommand : ICommand    {        Readonly Action<object> _execute;        Readonly Predicate<object> _canExecute;        /// <summary>        /// Creates a new command that can always execute.        /// </summary>        /// <param name="execute">The execution logic.</param>        public RelayCommand(Action<object> execute)            : this(execute,null)        {        }        /// <summary>        /// Creates a new command.        /// </summary>        /// <param name="execute">The execution logic.</param>        /// <param name="canExecute">The execution status logic.</param>        public RelayCommand(Action<object> execute,Predicate<object> canExecute)        {            if (execute == null)                throw new ArgumentNullException("execute");            _execute = execute;            _canExecute = canExecute;        }        [DeBUGgerStepThrough]        public bool CanExecute(object parameter)        {            return _canExecute == null ? true : _canExecute(parameter);        }        public event EventHandler CanExecuteChanged        {            add { CommandManager.RequerySuggested += value; }            remove { CommandManager.RequerySuggested -= value; }        }        public voID Execute(object parameter)        {            _execute(parameter);        }    }}

这是我创建用户的用户存储库:

using System.Collections.ObjectModel;using System.linq;using System.Text;using System.Threading.Tasks;using WpfAppDataGrID.Model;namespace WpfAppDataGrID.DataAccess{    public class UserRepository    {        ObservableCollection<User> _users = new ObservableCollection<User>();        public UserRepository()        {        }        public ObservableCollection<User> GetUsers()        {            return _users;        }        public voID LoadUsers()        {            int i = 0;            while (i < 1000)            {                i++;                var user = new User();                user.User_ID = i;                user.Username = RandomString(8,true);                user.name = user.Username + " " + RandomString(8,true);                user.Job_Title = RandomString(8,true);                user.Department = RandomString(8,true);                user.Company = RandomString(10,true);                user.Phone_Office = "07 " + RandomNumber(5200,6700) + " " + RandomNumber(1000,9999);                user.Phone_Mobile = "04 " + RandomNumber(2800,4500) + " " + RandomNumber(1000,9999);                user.Email = user.Username + "@gmail.com";                _users.Add(user);            }        }        private static Random randomSeed = new Random();        public static string RandomString(int size,bool lowerCase)        {            StringBuilder RandStr = new StringBuilder(size);            int Start = (lowerCase) ? 97 : 65;            for (int i = 0; i < size; i++)                RandStr.Append((char)(26 * randomSeed.NextDouble() + Start));            return RandStr.ToString();        }        private int RandomNumber(int min,int max)        {            return randomSeed.Next(min,max);        }    }}

最后这里是所有用户的视图:

<Window x:Class="WpfAppDataGrID.VIEw.AllUsersVIEw"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:viewmodel="clr-namespace:WpfAppDataGrID.viewmodel"        title="AllUsersVIEw" Height="450" WIDth="820">    <Window.DataContext>        <viewmodel:AllUsersviewmodel />    </Window.DataContext>    <Window.Resources>        <Style x:Key="UserRowStyle" targettype="{x:Type DataGrIDRow}">            <Setter Property="IsSelected" Value="{Binding Path=IsSelected,Mode=TwoWay}" />            <Setter Property="borderBrush" Value="DarkGray" />            <Setter Property="borderThickness" Value="0,1,0"/>            <Setter Property="Background" Value="transparent"/>            <Setter Property="Foreground" Value="Black"/>            <Setter Property="Template">                <Setter.Value>                    <ControlTemplate targettype="{x:Type DataGrIDRow}">                        <GrID>                            <border x:name="DGR_backingborder" borderBrush="Orange" borderThickness="1,2,2" Background="transparent">                            </border>                            <border x:name="DGR_border"                                     borderBrush="{TemplateBinding borderBrush}"                                     borderThickness="1,2"                                     Background="{TemplateBinding Background}"                                    SnapsToDevicePixels="True">                                <SelectiveScrollingGrID>                                    <SelectiveScrollingGrID.ColumnDeFinitions>                                        <ColumnDeFinition WIDth="auto" />                                        <ColumnDeFinition WIDth="*" />                                    </SelectiveScrollingGrID.ColumnDeFinitions>                                    <SelectiveScrollingGrID.RowDeFinitions>                                        <RowDeFinition Height="*" />                                        <RowDeFinition Height="auto" />                                    </SelectiveScrollingGrID.RowDeFinitions>                                    <DataGrIDCellsPresenter x:name="DGR_CellsPresenter" GrID.Column="1" ItemsPanel="{TemplateBinding ItemsPanel}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />                                    <DataGrIDDetailsPresenter x:name="DGR_DetailsPresenter" GrID.Column="1" GrID.Row="1"                                                          SelectiveScrollingGrID.SelectiveScrollingOrIEntation="{Binding AreRowDetailsFroZen,ConverterParameter={x:Static SelectiveScrollingOrIEntation.Vertical},Converter={x:Static DataGrID.RowDetailsScrollingConverter},relativeSource={relativeSource AncestorType={x:Type DataGrID}}}"                                                          Visibility="{TemplateBinding DetailsVisibility}" />                                    <DataGrIDRowheader Foreground="White" GrID.rowspan="2" SelectiveScrollingGrID.SelectiveScrollingOrIEntation="Vertical"                                                   Visibility="{Binding headersVisibility,ConverterParameter={x:Static DataGrIDheadersVisibility.Row},Converter={x:Static DataGrID.headersVisibilityConverter},relativeSource={relativeSource AncestorType={x:Type DataGrID}}}" />                                </SelectiveScrollingGrID>                            </border>                        </GrID>                        <ControlTemplate.Triggers>                            <Trigger Property="IsMouSEOver" Value="True">                                <Setter Targetname="DGR_border" Property="borderBrush" Value="transparent" />                                <Setter Targetname="DGR_border" Property="borderThickness" Value="1,2" />                            </Trigger>                            <Trigger Property="IsSelected" Value="True">                                <Setter Targetname="DGR_border" Property="borderBrush" Value="DarkOrange"/>                                <Setter Targetname="DGR_border" Property="Background" Value="Orange"/>                            </Trigger>                        </ControlTemplate.Triggers>                    </ControlTemplate>                </Setter.Value>            </Setter>        </Style>        <Style targettype="{x:Type DataGrIDCell}" >            <Setter Property="Background" Value="transparent"/>            <Setter Property="borderBrush" Value="transparent"/>            <Setter Property="borderThickness" Value="0" />            <Setter Property="Foreground" Value="Black" />        </Style>    </Window.Resources>    <GrID name="grIDUsers" Background="transparent">        <DockPanel Background="transparent" margin="2,10,2" >            <GrID DockPanel.Dock="Bottom" margin="0,4,2">                <StackPanel HorizontalAlignment="Right" OrIEntation="Horizontal" VerticalAlignment="Center">                    <button Content="Select rows 5 to 50" Command="{Binding SelectItemsCommand}"/>                    <TextBlock Text=" Total: " />                    <ContentPresenter Content="{Binding  Elementname=GenericdataGrID,Path=ItemsSource.Count}" ContentStringFormat="0" />                </StackPanel>            </GrID>            <DataGrID name="GenericdataGrID" Background="transparent"                        RowStyle="{StaticResource UserRowStyle}"                      borderThickness="0"                       CanUserReorderColumns="True"                       autoGenerateColumns="False"                       ItemsSource="{Binding UserCollection}"                       HorizontalScrollbarVisibility="auto" VerticalScrollbarVisibility="auto"                      CanUserAddRows="False">                <DataGrID.Columns>                    <DataGrIDTextColumn header="ID" CanUserReorder="True" IsReadonly="True" Binding="{Binding Path=User_ID,NotifyOnTargetUpdated=True}" />                    <DataGrIDTextColumn header="name" CanUserReorder="True" CanUserSort="True" Binding="{Binding Path=name}"/>                    <DataGrIDTextColumn header="Username" CanUserReorder="True" CanUserSort="True" Binding="{Binding Path=Username}"/>                    <DataGrIDTextColumn header="Job Title" CanUserReorder="True" CanUserSort="True" Binding="{Binding Path=Job_Title}"/>                    <DataGrIDTextColumn header="Department" CanUserReorder="True" CanUserSort="True" Binding="{Binding Path=Department}"/>                    <DataGrIDTextColumn header="Company" CanUserReorder="True" CanUserSort="True" Binding="{Binding Path=Company}"/>                    <DataGrIDTextColumn header="Phone" CanUserReorder="True" CanUserSort="True" Binding="{Binding Path=Phone_Office}"/>                    <DataGrIDTextColumn header="Mobile" CanUserReorder="True" CanUserSort="True" Binding="{Binding Path=Phone_Mobile}"/>                    <DataGrIDTextColumn header="eMail" CanUserReorder="True" CanUserSort="True" Binding="{Binding Path=Email}"/>                </DataGrID.Columns>            </DataGrID>        </DockPanel>    </GrID></Window>
解决方法 汉克

禁用虚拟化肯定会以性能成本解决您的问题.

您可以禁用VirtualizeStackPanel的回收,如@nit建议的那样,但这不能完全解决问题.

另一种方法是使用附加行为.

@Samuel Jack有一个经过测试的工作解决方案(之前使用过),它适用于列表框和MVVM,效果很好.
所选项目可以双向模式绑定.

http://blog.functionalfun.net/2009/02/how-to-databind-to-selecteditems.html

就像ListBox一样,我为DataGrID上传了一个修改过的解决方案,它是一个具有所需功能的基本DataGrID.

https://www.sugarsync.com/pf/D6837746_80955217_331798

请享用

总结

以上是内存溢出为你收集整理的c# – 为什么DataGridRow IsSelected绑定不能在DataGrid上运行全部内容,希望文章能够帮你解决c# – 为什么DataGridRow IsSelected绑定不能在DataGrid上运行所遇到的程序开发问题。

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

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

原文地址: https://outofmemory.cn/langs/1243916.html

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

发表评论

登录后才能评论

评论列表(0条)

保存