c# – DataGrid选择列
我试图以编程方式选择
WPF DataGrid中的整个列.我的代码似乎工作,但它真的很慢!我猜这是因为它不断调用ScrollIntoView.有人可以帮助我找到加速它的解决方案或选择整个列的替代方案吗?
public static void SelectColumn(DataGrid grid,int column) { for (int i = 0; i < grid.Items.Count; i++) { // Select each cell in this column var cell = DataGridHelper.GetCell(grid,i,column); if (cell != null) { cell.IsSelected = true; } } DataGridHelper.GetCell(grid,column).Focus(); } public static DataGridCell GetCell(DataGrid grid,int row,int column) { DataGridRow rowContainer = GetRow(grid,row); if (rowContainer != null) { DataGridCellsPresenter presenter = TreeHelper.GetVisualChild<DataGridCellsPresenter>(rowContainer); if (presenter == null) { // may be virtualized,bring into view and try again grid.ScrollIntoView(rowContainer,grid.Columns[column]); presenter = TreeHelper.GetVisualChild<DataGridCellsPresenter>(rowContainer); } if (presenter != null) { // try to get the cell but it may possibly be virtualized DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column); if (cell == null) { // may be virtualized,bring into view and try again grid.ScrollIntoView(rowContainer,grid.Columns[column]); cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column); } return cell; } } return null; } public static DataGridRow GetRow(DataGrid grid,int index) { DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index); if (row == null) { // may be virtualized,bring into view and try again grid.ScrollIntoView(grid.Items[index]); row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index); } return row; } 更新: 我正在尝试@ianschol建议的解决方案.这就是我所拥有的(我在b / c后面的代码中绑定我不知道在运行时需要多少列): for (int i = 0; i < this.CurrentData.Data[0].Length; i++) { TheGrid.Columns.Add( new DataGridTextColumn { Header = (this.CurrentData.Rank > 1) ? string.Format(this.culture,headerFormatString,i + 1) : string.Empty,Binding = new Binding(string.Format("[{0}].DataValue",i)) { ValidatesOnDataErrors = true,UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged },Width = DataGridLength.Auto,ElementStyle = new Style { TargetType = typeof(TextBlock),Triggers = { this.errorTrigger } },EditingElementStyle = new Style { TargetType = typeof(TextBox),CellStyle = new Style { TargetType = typeof(DataGridCell),Setters = { new Setter { Property = DataGridCell.IsSelectedProperty,Value = new Binding(string.Format("[{0}].IsSelected",i)) { Mode = BindingMode.TwoWay,} },} }); } 和我的IsSelected财产: private bool isSelected = false; public bool IsSelected { get { return this.isSelected; } set { this.isSelected = value; OnPropertyChanged("IsSelected"); } } 而新的SelectColumn代码: public static void SelectColumn(DataGrid grid,int column) { for (int i = 0; i < grid.Items.Count; i++) { // Select each cell in this column ((DataItem[])(grid.Items[i]))[column].IsSelected = true; } } 问题是,如果我在代码中更新IsSelected属性,它会更新GUI(有点,它古怪),但反之亦然.即如果我在GUI中选择一个单元格/行,它不会在代码中调用属性设置器.你可以看到绑定是TwoWay所以我不确定这个问题. 另一个更新:问题似乎与虚拟化有关.如果我关闭虚拟化(VirtualizingStackPanel.IsVirtualizing =“False”),它可以正常工作. 解决方法
一种更有效的方法可能是在DataSource的类上使用IsSelected属性,这样每列都有一个相应的“IsSelected”属性.
public class MyData : INotifyPropertyChanged { private string name; public string Name { get { return name; } set { name = value; Notify("Name"); } } private bool nameSelected = false; public bool NameSelected { get { return nameSelected; } set { nameSelected = value; Notify("NameSelected"); } } //... etc ... } 接下来,您可以更改每个Column的CellStyle,以将单元格的IsSelected属性绑定到类上的相关IsSelected属性. <DataGrid ItemsSource="{Binding Users}" AutoGenerateColumns="False" HorizontalAlignment="Left" Name="scratchGrid" CanUserAddRows="False" VerticalScrollBarVisibility="Auto" SelectionUnit="Cell"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Name}" Header="User Name" Width="200"> <DataGridTextColumn.CellStyle> <Style TargetType="{x:Type DataGridCell}"> <Setter Property="IsSelected" Value="{Binding NameSelected}" /> </Style> </DataGridTextColumn.CellStyle> </DataGridTextColumn> <DataGridTextColumn Binding="{Binding Age}" Header="User Age" Width="80"> <DataGridTextColumn.CellStyle> <Style TargetType="{x:Type DataGridCell}"> <Setter Property="IsSelected" Value="{Binding AgeSelected}" /> </Style> </DataGridTextColumn.CellStyle> </DataGridTextColumn> </DataGrid.Columns> </DataGrid> 最后,像这样实现你的select-all代码(这会在Age上选择all,你可能希望做一个更通用/更优雅的实现;)): foreach (MyData user in Users) { user.AgeSelected = true; } 您必须注意确保所有NotifyPropertyChanged行为都排成一行,因为您希望网格能够识别其绑定集合中的属性正在更新. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |