更改DataGrid WPF中单元格的背景色

更改DataGrid WPF中单元格的背景色,wpf,converter,wpfdatagrid,dataview,Wpf,Converter,Wpfdatagrid,Dataview,我使用以下链接在表格中显示我的二维数据: 除了背景色没有改变(甚至没有点击转换器方法)之外,所有功能都正常工作。有人能告诉我发生了什么事吗? 下面我将发布一个完整的、最少的示例。我对这些想法都没有兴趣(例如,使用DataView绑定我的IEnumerable>),所以请随意建议其他方法。我唯一的硬性要求是,在我的实际项目中,数据以IEnumerable> 代码如下: public partial class MainWindow : Window { public MainWindo

我使用以下链接在表格中显示我的二维数据:

除了背景色没有改变(甚至没有点击转换器方法)之外,所有功能都正常工作。有人能告诉我发生了什么事吗?

下面我将发布一个完整的、最少的示例。我对这些想法都没有兴趣(例如,使用DataView绑定我的IEnumerable>),所以请随意建议其他方法。我唯一的硬性要求是,在我的实际项目中,数据以IEnumerable>

代码如下:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        ViewModel vm = new ViewModel();

        List<Column> row1 = new List<Column>()
        {
            new Column(){Make = Make.Ford,OperatingStatus =  OperatingStatus.Broken},
            new Column(){Make = Make.Honda, OperatingStatus = OperatingStatus.Unknown}
        };
        List<Column> row2 = new List<Column>()
        {
            new Column() {Make = Make.GM, OperatingStatus = OperatingStatus.Working},
            new Column() {Make = Make.Toyota, OperatingStatus = OperatingStatus.Broken}
        };

        List<List<Column>> data = new List<List<Column>>();
        data.Add(row1);
        data.Add(row2);
        vm.Data = data;
        DataContext = vm;

    }
}

public enum OperatingStatus
{
    Working = 0,
    Broken = 1,
    Unknown = 2
}

public enum Make
{
    Ford,
    Honda,
    GM,
    Toyota
}

public class Column
{
    public Make Make { get; set; }
    public OperatingStatus OperatingStatus { get; set; }
}
public class ViewModel
{
    public IEnumerable<IEnumerable<Column>>  Data { get; set; }

    public DataView MyDataTable
    {
        get
        {
            var rows = Data.Count();
            var cols = Data.First().Count();
            var t = new DataTable();
            for (var c = 0; c < cols; c++)
            {
                t.Columns.Add(new DataColumn(c.ToString()));
            }

            foreach (var row in Data)
            {
                var newRow = t.NewRow();
                int c = 0;
                foreach (var col in row)                 
                {
                    newRow[c] = col.Make;
                    c++;
                }
                t.Rows.Add(newRow);
            }
            return t.DefaultView;
        }
    }
}

public class NameToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string input = value as string;
        switch (input)
        {
            case "Ford":
                return Brushes.LightGreen;
            case "GM":
                return Brushes.Red;
            case "Toyota":
                return Brushes.Blue;
            case "Honda":
                return Brushes.Yellow;
            default:
                return DependencyProperty.UnsetValue;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
ViewModel vm=新的ViewModel();
列表行1=新列表()
{
新列(){Make=Make.Ford,OperatingStatus=OperatingStatus.break},
新列(){Make=Make.Honda,OperatingStatus=OperatingStatus.Unknown}
};
列表行2=新列表()
{
新列(){Make=Make.GM,OperatingStatus=OperatingStatus.Working},
新列(){Make=Make.Toyota,OperatingStatus=OperatingStatus.break}
};
列表数据=新列表();
添加数据(第1行);
添加数据(第2行);
vm.Data=数据;
DataContext=vm;
}
}
公共枚举操作状态
{
工作=0,
断开=1,
未知=2
}
公共枚举生成
{
河流浅水处
本田,
转基因的
丰田
}
公共类专栏
{
公共Make Make{get;set;}
公共操作状态操作状态{get;set;}
}
公共类视图模型
{
公共IEnumerable数据{get;set;}
公共数据视图MyDataTable
{
得到
{
var rows=Data.Count();
var cols=Data.First().Count();
var t=新数据表();
对于(var c=0;c
这是XAML

<Window x:Class="StackOverFlowDataGridQuestion.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:StackOverFlowDataGridQuestion"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.Resources>
    <local:NameToBrushConverter x:Key="NameToBrushConverter"/>
</Window.Resources>
<Grid>
    <ScrollViewer>
        <DataGrid Width="1000"
                  Margin="0"
                  HorizontalAlignment="Left"                   
                  DataContext="{Binding}"                      
                  ItemsSource="{Binding MyDataTable}"      >

            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Make}">
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="Background" Value="{Binding Make, Converter={StaticResource NameToBrushConverter}}"/>
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </ScrollViewer>
</Grid>
<Window x:Class="StackOverFlowDataGridQuestion.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:StackOverFlowDataGridQuestion"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.Resources>
    
    <local:ConverterHoldoffGridColor x:Key="bgHoldoffGridColor" />
    <Style x:Key="CellHighlighterStyle">

       
        <Setter Property="DataGridCell.Background">
            <Setter.Value>
                <MultiBinding
                Converter="{StaticResource bgHoldoffGridColor}" >
                    <MultiBinding.Bindings>
                        <Binding RelativeSource="{RelativeSource Self}"/>
                        <Binding Path="Row" Mode="OneWay"/>
                    </MultiBinding.Bindings>
                </MultiBinding>
            </Setter.Value>
        </Setter>

       
    </Style>
</Window.Resources>
<Grid>
    <ScrollViewer>
        <DataGrid x:Name="myDataGrid" CellStyle="{StaticResource CellHighlighterStyle}" 
            DataContext="{Binding }"                      
                  ItemsSource="{Binding MyDataTable}">

           
        </DataGrid>
        
    </ScrollViewer>
</Grid>

在尝试了Nik的建议并在两处将“Make”替换为“Row[0]”之后,我得到了以下结果,这是一个进步,因为有一些颜色!如果有更多的变化,我会在这里报告

我本以为福特广场是绿色的,本田是黄色的,通用是红色的,丰田是蓝色的。类似于下面的内容(请原谅我糟糕的标记技巧)


这是使用
数据视图作为项目资源的不幸副作用之一。在本例中,
DataGridRow
的DataContext是一个
DataRowView
,它有一个属性
Row
。此属性包含单个单元格的值数组
DataGridCell
继承了
DataContext
。然后您要查找的是第一列的
行[0]
,第二列的
行[1]
,依此类推。将下面的XAML用于
DataGridTextColumn
,生成了您在我的测试中寻找的结果,我在绑定中使用了
Row[0]
而不是
Make
。感谢您提供了这么好的工作代码,节省了这么多时间

<DataGridTextColumn Binding="{Binding Row[0]}">
  <DataGridTextColumn.ElementStyle>
    <Style TargetType="{x:Type TextBlock}">
      <Setter Property="Background" Value="{Binding Row[0], Converter={StaticResource NameToBrushConverter}}"/>
    </Style>
  </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

我最近需要做一些类似的事情,我的输入必须是一个不确定维度的二维数组。我最终制作了一个可重用的自定义控件,扩展了
DataGrid
。这个控件管理自己的DataContext(一个
DataTable
),这使得UI非常干净,无需使用索引或任何代码


也许有更好的办法,但我想不出来。另外,这真的取决于你想要实现什么。如果您的列在设计时是已知的,那么我将考虑创建包含对象的ExababeLink。如果没有,也许有人有更好的技巧,但至少这应该能让你的代码正常工作。

这是一个面向子孙后代的解决方案。我不认为这是最好的或最优雅的,我欢迎其他的想法。特别是,必须公开数据视图而不仅仅是
IEnumerable
的整个想法似乎很疯狂

除了我最初提到的文章外,我还发现以下内容非常有用:

代码

公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
ViewModel vm=新的ViewModel();
列表行1=新列表()
{
新列(){Make=Make.Ford,OperatingStatus=OperatingStatus.break},
新列(){Make=Make.Ho
<Window x:Class="StackOverFlowDataGridQuestion.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:StackOverFlowDataGridQuestion"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.Resources>
    
    <local:ConverterHoldoffGridColor x:Key="bgHoldoffGridColor" />
    <Style x:Key="CellHighlighterStyle">

       
        <Setter Property="DataGridCell.Background">
            <Setter.Value>
                <MultiBinding
                Converter="{StaticResource bgHoldoffGridColor}" >
                    <MultiBinding.Bindings>
                        <Binding RelativeSource="{RelativeSource Self}"/>
                        <Binding Path="Row" Mode="OneWay"/>
                    </MultiBinding.Bindings>
                </MultiBinding>
            </Setter.Value>
        </Setter>

       
    </Style>
</Window.Resources>
<Grid>
    <ScrollViewer>
        <DataGrid x:Name="myDataGrid" CellStyle="{StaticResource CellHighlighterStyle}" 
            DataContext="{Binding }"                      
                  ItemsSource="{Binding MyDataTable}">

           
        </DataGrid>
        
    </ScrollViewer>
</Grid>