【问题标题】:WPF: Change DataGrid cell/row background color dynamically at runtimeWPF:在运行时动态更改 DataGrid 单元格/行背景颜色
【发布时间】:2016-06-26 08:24:36
【问题描述】:

我有多个绑定到 DataTable 的 DataGrid,这些 DataTable 是使用 SQL 动态创建的。每当 DataTable 记录发生更改(添加、修改、删除)时,DataGridCells 都应相应更改其背景颜色(绿色=新、黄色=修改等)。

在 WinForms 中,我使用 _RowPostPaint 更改了 DataGridView 的背景颜色(代码非常简化):

private void DataGridViewTest_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
    DataRow row = (this.Rows[e.RowIndex].DataBoundItem as DataRowView).Row;
    switch (row.RowState)
    {
        case DataRowState.Added:
            myBitmap = new Bitmap(imageList.Images[1]);
            this[0, e.RowIndex].Style.BackColor = CellChangesColorAdded;
            break;
        case DataRowState.Modified:
            string sValOld = row[0, DataRowVersion.Original].ToString();
            string sValNew = row[0].ToString();
            if (sValOld != sValNew)
            {
                this[0, e.RowIndex].Style.BackColor = CellChangesColorMod;
            }
            break;
        case DataRowState.Deleted:
            this[0, e.RowIndex].Style.BackColor = CellChangesColorDel;
            break;
    }
}

我不想像 countless examples like this 那样在 XAML 中对列依赖项进行硬编码,因为它们是在运行时创建的,而且我有许多 DataGrids 正在使用中。

尝试使用 DataGrid_CellEditEnding 失败,因为它不会在排序等时保留更改:

XAML:

<Window.Resources>
    <Style x:Key="MyStyle" TargetType="{x:Type DataGridCell}">
        <Setter Property="Background" Value="Green" />
    </Style>
</Window.Resources>
<DataGrid x:Name="dataGrid" Grid.Row="4" Grid.ColumnSpan="6"
    ItemsSource="{Binding}"
>
</DataGrid>

.cs:

dataGrid.DataContext = dataTable.DefaultView; // Table filled by SQL query
dataGrid.CellEditEnding += dataGrid_CellEditEnding;

// Problem: Color changes disappear when user sorts DataGrid
    private void dataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        if (e.EditAction == DataGridEditAction.Commit)
        {
            TextBox tb = e.EditingElement as TextBox;
            DataGridCell cell = tb.Parent as DataGridCell;
            // evaluate row changes and change color accordingly
            //cell.Background = new SolidColorBrush(Colors.Yellow); // set style instead of color
            cell.Style = (Style)this.Resources["MyStyle"]; // color is changed to green, according to defined style
        }
    }

这可以很好地改变背景颜色,但是在对 DataGrid 等进行排序时不会保留样式。

如何确保保持颜色变化?在我看来,最好的解决方案是以某种方式将 DataRows 绑定到一个辅助类,并在 DataTable 更改时返回相应的样式。但是我还没有看到任何例子。

【问题讨论】:

  • 我认为这将是艰难的。如果不将dataTable.DefaultView 包装在管理单元格当前状态的辅助类中,我将看不到这个工作。我的猜测是重新排序 DataGrid 会刷新所有绘制的单元格,并且因为 DataGrid 将是唯一知道如何绘制特定单元格的人,所以它会忘记它。 DataGrid 需要知道从数据中如何为每个单元格着色。
  • @MarkusHütter 是的,我也是这么想的,我基本上知道如何为特定的类或硬编码的 XAML 使用帮助类。我还没有看到任何处理我的问题的示例,并且一直在弄清楚如何为绑定的 DataTable 使用帮助器类。

标签: c# wpf xaml dynamic datagrid


【解决方案1】:

为了完整性:

如果您真的打算在运行时更改颜色,则可以忽略 MVVM,例如使用 DataGrid_LoadingRow,检查它的 DataContext(在本例中为 DataRowView)并从那里继续:

// Changes beeing made to the entire row in this case
private void DgModules_LoadingRow(object sender, DataGridRowEventArgs e)
{
    DataGridRow gridRow = e.Row;
    DataRow row = (gridRow.DataContext as DataRowView).Row;
    switch (row.RowState)
    {
        case DataRowState.Added:
            gridRow.Background = new SolidColorBrush(Colors.Green);
            break;
        case DataRowState.Modified:
            gridRow.Background = new SolidColorBrush(Colors.Yellow);
            break;
        case DataRowState.Deleted:
            gridRow.Background = new SolidColorBrush(Colors.Red);
            break;
    }
}

如果您想实际使用 MVVM 来解决这个问题,请选择 this solution

【讨论】:

    猜你喜欢
    • 2020-04-18
    • 2018-09-26
    • 2013-03-16
    • 2015-05-14
    • 2011-04-03
    • 2013-01-28
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多