动态更改数据网格行单元格前景色WPF

时间:2019-12-28 14:23:45

标签: c# wpf datagrid foreground

在我的wpf项目中,我有一个数据网格,其中的单元绑定到不同的东西。这是xaml:

<DataGrid x:Name="Tasks" CanUserDeleteRows="True">
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="Coloumn1" Binding="{Binding C1}"/>
                            <DataGridTextColumn Header="Coloumn2" Binding="{Binding C2}"/>
                            <DataGridTextColumn Header="Coloumn3" Binding="{Binding C3}"/>
                            <DataGridTextColumn Header="Coloumn4" Binding="{Binding C4}"/>
                            <DataGridTextColumn Header="Coloumn5" Binding="{Binding C5}"/>
                            <DataGridTextColumn Header="Coloumn6" Binding="{Binding C6}"/>
                            <DataGridTextColumn Header="Coloumn7" Binding="{Binding C7}"/>
                            <DataGridTextColumn Header="Coloumn8" Binding="{Binding C8}"/>
                        </DataGrid.Columns>
                        <DataGrid.ContextMenu>
                            <ContextMenu>
                                <MenuItem Header="Add task" Click="ADDtask_Click" FontSize="11">
                                </MenuItem>
                            </ContextMenu>
                        </DataGrid.ContextMenu>
                    </DataGrid>

对于我的C#代码,我有以下内容:

public Guid 8 { get; }
public string 7 { get; set; }
public string 6 { get; set; }
public string 5 { get; set; }
public string 4 { get; set; }
public string 3 { get; set; }
public string 2 { get; set; }
public string 1 { get; set; }
public Result(string c1, string c2, string c3, string c4, string c5, string c6, string c7, string c8)
{
    this.Identifier = Guid.NewGuid();
    this.8 = c1;
    this.7 = c2;
    this.6 = c3;
    this.5 = c4;
    this.4 = c5;
    this.3 = c6;
    this.2 = c7;
    this.1 = c8;
}

private void Start_Task_Click(object sender, RoutedEventArgs e)
{
    System.Windows.Controls.Button button = (System.Windows.Controls.Button)sender;
    Result task = (Result)button.DataContext;
    if(...)
    {
        ????
    }
    else
    {
        return;
    }
}

    public string idlestatus = "idle";

    private void Button_Click1(object sender, RoutedEventArgs e) //this adds the columns to the datagrid
{
    Tasks.Items.Add(new Result(textbox1.Text, textbox2.Text, textbox3.Text, textbox4.Text, textbox5.Text, textbox6.Text, textbox7.Text, idlestatus));


}

我想制作一个if语句:

if(task.c1 == "...") {
cell.Style.Foreground.Color = ...
}

我该怎么做?我已经尝试做过这样的事情:

Tasks.CellStyle.Style.Foreground.Color

但是它不起作用,任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

您有一些选择。由于您不使用自动生成的列,因此可以使用ElementStyle的{​​{1}}属性:

DataGridColumn

或使用<DataGrid x:Name="Tasks"> <DataGrid.Resources> <Style x:Key="ElementStyle" TargetType="TextBlock"> <Style.Triggers> <Trigger Property="Text" Value="Error Predicate Text"> <Setter Property="Foreground" Value="Red" /> </Trigger> <Trigger Property="Text" Value="Good Predicate Text"> <Setter Property="Foreground" Value="Green" /> </Trigger> </Style.Triggers> </Style> </DataGrid.Resources> <DataGrid.Columns> <DataGridTextColumn Header="Column1" Binding="{Binding C1}" ElementStyle="{StaticResource ElementStyle}" /> <DataGridTextColumn Header="Column2" Binding="{Binding C2}" ElementStyle="{StaticResource ElementStyle}" /> </DataGrid.Columns> </DataGrid>

DataTrigger

当触发器应独占特定列的单个单元格(而不是基于单元格值的整个行)时,必须使用<DataGrid x:Name="Tasks"> <DataGrid.Columns> <DataGridTextColumn Header="Column1" Binding="{Binding C1}" /> <DataGridTextColumn Header="Column2" Binding="{Binding C2}" /> </DataGrid.Columns> <DataGrid.CellStyle> <Style TargetType="DataGridCell"> <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text}" Value="Error Predicate Text" /> <Setter Property="Foreground" Value="Red" /> </DataTrigger> </Style.Triggers> </Style> </DataGrid.CellStyle> </DataGrid> 来检查当前列标题:

MultiDataTrigger

另一种解决方案是使用<DataGrid x:Name="Tasks"> <DataGrid.Columns> <DataGridTextColumn Header="Column1" Binding="{Binding C1}" /> <DataGridTextColumn Header="Column2" Binding="{Binding C2}" /> </DataGrid.Columns> <DataGrid.CellStyle> <Style TargetType="DataGridCell"> <Style.Triggers> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=Column.Header}" Value="Column1" /> <Condition Binding="{Binding C1}" Value="Error Predicate Text" /> </MultiDataTrigger.Conditions> <Setter Property="Foreground" Value="Red" /> </MultiDataTrigger> </Style.Triggers> </Style> </DataGrid.CellStyle> </DataGrid> (或出于与上述IValueConverter相同的原因使用IMultiValueConverter):

MultiDataTrigger

CellForegroundMultiValueConverter.cs

<DataGrid x:Name="Tasks">
  <DataGrid.Columns>
    <DataGridTextColumn Header="Column1"
                        Binding="{Binding C1}" />
    <DataGridTextColumn Header="Column2"
                        Binding="{Binding C2}" />
  </DataGrid.Columns>
  <DataGrid.CellStyle>
    <Style TargetType="DataGridCell">
      <Setter Property="Foreground">
        <Setter.Value>
          <MultiBinding>
            <MultiBinding.Converter>
              <CellForegroundMultiValueConverter />
            </MultiBinding.Converter>

            <Binding RelativeSource="{RelativeSource Self}"
                     Path="Column.Header"/>
            <Binding />
            <Binding Path="HasChanges" />
          </MultiBinding>
        </Setter.Value>
      </Setter>
    </Style>
  </DataGrid.CellStyle>
</DataGrid>

Result.cs

class CellForegroundMultiValueConverter : IMultiValueConverter
{
  #region Implementation of IMultiValueConverter

  /// <inheritdoc />
  public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
  {
    var columnHeader = values[0] as string;
    var dataItem = values[1] as Result;
    return columnHeader.Equals("Column1", StringComparison.OrdinalIgnoreCase) 
           && dataItem.C1.Equals("....", StringComparison.OrdinalIgnoreCase)
      || columnHeader.Equals("Column2", StringComparison.OrdinalIgnoreCase) 
           && dataItem.C2.Equals("....", StringComparison.OrdinalIgnoreCase)
      ? Brushes.Red
      : Brushes.Black;
  }

  public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotSupportedException();

  #endregion
}