如何在WPF DataGrid中更改某些单元格的背景颜色?

时间:2016-07-13 10:04:40

标签: c# wpf datagrid

我有一个绑定到对象集合的数据网格。

对象的一个​​属性是存储颜色值的字符串。

my dataGrid

在此“COLORBACKGROUND”单元格上单击,将打开一个颜色选择器以更改它。

我需要的是通过datagrid行(#RGB)中显示的值更改单元格的背景颜色。

<DataGrid SelectionUnit="Cell" SelectedCellsChanged="DgDataTable_OnSelectedCellsChanged" x:Name="DgDataTable" Grid.Row="0" Grid.ColumnSpan="2" Margin="10,20,10,0" AutoGenerateColumns="true" HeadersVisibility="All" RowHeaderWidth="20" Style="{StaticResource AzureDataGrid}" GridLinesVisibility="Horizontal" LoadingRow="dgDataTable_LoadingRow" ColumnHeaderHeight="10" AlternatingRowBackground="{DynamicResource {x:Static SystemColors.GradientActiveCaptionBrushKey}}" AutoGeneratingColumn="DgDataTable_AutoGeneratingColumn">
    <DataGrid.RowHeaderStyle>
        <Style TargetType="DataGridRowHeader">
            <Setter Property="FontSize" Value="10"/>
            <Setter Property="Background" Value="LightCyan"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
        </Style>
    </DataGrid.RowHeaderStyle>
    <DataGrid.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="TextBlock.TextAlignment" Value="Center"/>
          <!--  <Style.Triggers>
                <Trigger Property="Text" Value="John">
                    <Setter Property="Background" Value="LightGreen"/>
                </Trigger>
            </Style.Triggers> -->
        </Style>
    </DataGrid.CellStyle>
</DataGrid>

我尝试使用AutoGenerating列:

private void DgDataTable_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    if (e.PropertyName == "SrcAlert")
    {
        DataGridComboBoxColumn cb = new DataGridComboBoxColumn();
        e.Column = cb;
        cb.ItemsSource = new List<string> {"1", "2"};
        cb.SelectedValueBinding = new Binding("SrcAlert");
        e.Column.Header = "SrcAlert";
    }
    if (e.PropertyName.Equals("ColorBackground"))
    {
        DataGridTextColumn tc = new DataGridTextColumn();
        e.Column = tc;
        tc.Foreground = (Color)ColorConverter.ConvertFromString(DgDataTable.CurrentCell.Item.ColorBackground);
    }
}

这个Item.ColorBackground没有编译......我把它作为我的解释,这就是我需要的。

我尝试了另一种解决方案:

if (e.PropertyName.Equals("ColorBackground"))
{
    string s = DgDataTable.CurrentCell.Item.ToString();
    e.Column.CellStyle.Setters.Add(new Setter(DataGridCell.BackgroundProperty, (Color)ColorConverter.ConvertFromString(s)));
}

但这是一次失败。

感谢您的帮助!

<小时/> 编辑:ASh解决方案的屏幕截图,非常适合我:

enter image description here

编辑:我使用颜色选择器调整了多个列的解决方案:

enter image description here

我添加样式设置器以仅在单元格中显示颜色:

    <Style TargetType="DataGridCell" x:Key="ColorPickerCellBG" 
       BasedOn="{StaticResource CommonCell}">
        <Setter Property="Background" Value="{Binding Path=BG}"/>
        <Setter Property="Foreground" Value="Transparent"/>
        <Setter Property="Width" Value="30"></Setter>
    </Style>
    <Style TargetType="DataGridCell" x:Key="ColorPickerCellAL" 
       BasedOn="{StaticResource CommonCell}">
        <Setter Property="Background" Value="{Binding Path=AL}"/>
        <Setter Property="Foreground" Value="Transparent"/>
        <Setter Property="Width" Value="30"></Setter>
    </Style>
    <Style...

单击单元格时,rgb颜色值可见,样式必须为“ClickedCell”... 我该如何改进?

2 个答案:

答案 0 :(得分:3)

可以将特殊样式应用于单个自动生成的列。

在资源中声明两个单元格样式

<Window.Resources>
    <Style TargetType="DataGridCell" x:Key="CommonCell"
           BasedOn="{StaticResource {x:Type DataGridCell}}">
        <Setter Property="TextBlock.TextAlignment" Value="Center"/>
    </Style>

    <Style TargetType="DataGridCell" x:Key="ColorPickerCell" 
           BasedOn="{StaticResource CommonCell}">
        <Setter Property="Background" Value="{Binding Path=ColorBackground}"/>
    </Style>
</Window.Resources>

ColorPickerCell继承了CommonCell样式。

<DataGrid SelectionUnit="Cell" 
          x:Name="DgDataTable" 
          AutoGenerateColumns="true" HeadersVisibility="All" RowHeaderWidth="20" 
          GridLinesVisibility="Horizontal" 
          ColumnHeaderHeight="10" 
          AlternatingRowBackground="{DynamicResource {x:Static SystemColors.GradientActiveCaptionBrushKey}}" 

          CellStyle="{StaticResource CommonCell}"
          AutoGeneratingColumn="DgDataTable_AutoGeneratingColumn">

    <DataGrid.RowHeaderStyle>
        <Style TargetType="DataGridRowHeader">
            <Setter Property="FontSize" Value="10"/>
            <Setter Property="Background" Value="LightCyan"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
        </Style>
    </DataGrid.RowHeaderStyle>

</DataGrid>

更改生成列的CellStyle

private void DgDataTable_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    if (e.PropertyName == "ColorBackground")
    {
        e.Column.CellStyle = (sender as DataGrid).FindResource("ColorPickerCell") as Style;
    }
}

答案 1 :(得分:1)

应用Converter,此Converter用于两个差异。目的因此返回两种差异类型。这种方法的优点是:您可以更改property本身的XAML。现在代码中无需更改,因此它对MVVM友好。

例如,在DataTrigger中将Value=BkgProp更改为Value=Name并查看。

示例XAML:

<Window ...>
    <Window.Resources>
        <local:PropBasedStringToColorConverter x:Key="StringToColorCnvKey"/>
    </Window.Resources>
    <Grid>
        <DataGrid x:Name="Dgrd">
        <DataGrid.Resources>
            <Style TargetType="DataGridCell">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding .Column, RelativeSource={RelativeSource Self}, Converter={StaticResource StringToColorCnvKey}}" Value="BkgProp">
                        <Setter Property="Background" Value="{Binding BkgProp, Converter={StaticResource StringToColorCnvKey}}"/>
                    </DataTrigger>
                </Style.Triggers>                    
            </Style>
        </DataGrid.Resources>
    </DataGrid>
    </Grid>
</Window>

示例数据:

Dgrd.ItemsSource = new[] { new { BkgProp = "#abcdef", Name = "Anjum" }, new { BkgProp = "#edf2ed", Name = "Anjum" }, new { BkgProp = "#ff0000", Name = "Anjum" } }.ToList();

转换器代码:

public class PropBasedStringToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        object result = null;

        if (value == null) return "N/A";

        if (value.GetType() == typeof(DataGridTextColumn))
        { 
            string path = ((Binding)((DataGridTextColumn)value).Binding).Path.Path;
            return path;
        }
        else if (value.GetType() == typeof(string))
        {
            result = new SolidColorBrush((Color)ColorConverter.ConvertFromString(value.ToString()));
        }
        return result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}