加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – DataGrid选择列

发布时间:2020-12-15 17:24:13 所属栏目:百科 来源:网络整理
导读:我试图以编程方式选择 WPF DataGrid中的整个列.我的代码似乎工作,但它真的很慢!我猜这是因为它不断调用ScrollIntoView.有人可以帮助我找到加速它的解决方案或选择整个列的替代方案吗? public static void SelectColumn(DataGrid grid,int column){ for (in
我试图以编程方式选择 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行为都排成一行,因为您希望网格能够识别其绑定集合中的属性正在更新.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读