代码之家  ›  专栏  ›  技术社区  ›  Magnetron

更改数据单元格颜色会更改其他单元格背景

  •  1
  • Magnetron  · 技术社区  · 7 年前

    我有一个DataGrid,在运行时用SQLite数据库中的数据填充它。当用户在datagrid中编辑单元格时,我希望该单元格更改其背景颜色。这是我所做的MCVE代码:

    public MainWindow()
    {
        InitializeComponent();
        DataTable dt = new DataTable();
        dt.Columns.Add("Column1");
        dt.Columns.Add("Column2");
        for (int i = 0; i < 100; i++)
        {
            var r = dt.NewRow();
            r[0] = i ;
            r[1] = i * i;
            dt.Rows.Add(r);
        }
        myDataGrid.ItemsSource = dt.DefaultView;
    }
    
    private void myDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        if (e.EditAction.ToString() == "Commit")
        {
            FrameworkElement element = e.Column.GetCellContent(e.Row);
            (element.Parent as DataGridCell).Background = new SolidColorBrush(Colors.Yellow);
        }
    }
    

    xaml:

    <Grid>
        <DataGrid x:Name="myDataGrid" CellEditEnding="myDataGrid_CellEditEnding"/>
    </Grid>
    

    问题是,每当我滚动时,我都会看到其他单元格也被涂成黄色。此外,根据我滚动的方式,黄色背景会从我想要的单元格跳到另一个单元格。只有当 EnableRowVirtualization 即将 true .有没有一种方法可以不禁用它,或者这是正确的方法?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Magnetron    7 年前

    我在网上找到了这个解决方案。我不知道这是不是正确的方法。我想这取决于你。

    我刚刚添加了一个虚拟化面板。VirtualizationMode=“Standard”到xaml:

        <DataGrid x:Name="myDataGrid" CellEditEnding="myDataGrid_CellEditEnding" VirtualizingStackPanel.VirtualizationMode="Standard" /> 
    

    我执行了这个命令,看到着色现在不会跳到其他细胞。

        2
  •  0
  •   AntiqTech    7 年前

    所以,根据Shou Risha link在回复中的评论,我想出了一个解决方案。禁用行虚拟化的问题是性能和内存,特别是对于大型网格。为了继续使用虚拟化并保持后台正常,我不得不取消 CleanUpVirtualizedItem 事件,如果任何行单元格具有背景色。

    xaml:

    <Grid>
        <DataGrid x:Name="myDataGrid" CellEditEnding="myDataGrid_CellEditEnding" VirtualizingStackPanel.CleanUpVirtualizedItem="myDataGrid_CleanUpVirtualizedItem"/>
    </Grid>
    

    代码隐藏:

    private void myDataGrid_CleanUpVirtualizedItem(object sender, CleanUpVirtualizedItemEventArgs e)
    {
        var row = e.UIElement as DataGridRow;
        for(int i = 0; i<(sender as DataGrid).Columns.Count; i++)
        {
            var cell = (DataGridCell)(sender as DataGrid).Columns[i].GetCellContent(row).Parent;
            if (cell.Background != Brushes.White) 
            {
                e.Cancel = true;
                break;
            }
        }            
    }