<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上运行所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)