繁体   English   中英

如何在后面的代码中更改 DataGrid(C#、WPF)单元格颜色(以编程方式)

[英]How to change DataGrid (C#, WPF) cell colour in the code behind (programmatically)

我有一个 DataGrid 并且在后面的代码中添加了列和行。

主窗口.xaml:

<DataGrid Name="dgResult" ItemsSource="{Binding}" AutoGenerateColumns="True" CanUserAddRows="False" ColumnWidth="*"/>

主窗口.xaml.cs:

private void AddItemsToDataGrid()
        {
            List<Measurement> measurements = new List<Measurement>()
            {
                new Measurement(){ Address="1", Pressure="10", ErrorTemps=new List<ErrorTemp>()
                {
                    new ErrorTemp(){Temp="10", Error="0.1", IsErrorOK =true}, new ErrorTemp() { Temp = "20", Error = "0.2", IsErrorOK =true }}
                },
                new Measurement(){ Address="1", Pressure="20", ErrorTemps=new List<ErrorTemp>()
                {
                    new ErrorTemp(){Temp="10", Error="0.2", IsErrorOK =true}, new ErrorTemp() { Temp = "20", Error = "0.3", IsErrorOK =true }}
                },
                new Measurement(){ Address="1", Pressure="30", ErrorTemps=new List<ErrorTemp>()
                {
                    new ErrorTemp(){Temp="10", Error="0.34", IsErrorOK =true}, new ErrorTemp() { Temp = "20", Error = "0.5", IsErrorOK =false }}
                }
            };

            DataTable dataTable = new DataTable();
            dataTable.Columns.Add(nameof(Measurement.Address));
            dataTable.Columns.Add(nameof(Measurement.Pressure));
            foreach(ErrorTemp error in measurements[0].ErrorTemps)
                dataTable.Columns.Add(nameof(error.Error)+"("+error.Temp +")");

            List<string> row;
            foreach (Measurement measurement in measurements)
            {
                row = new List<string>() { measurement.Address, measurement.Pressure };
                foreach (ErrorTemp error in measurement.ErrorTemps)
                    row.Add(error.Error);
                dataTable.Rows.Add(row.ToArray());
            }
            dgResult.ItemsSource = dataTable.DefaultView;//bez default view jest źle
        }

测量.cs:

namespace DataGridCodeBehind
{
    public class Measurement
    {
        public string Address { get; set; }
        public string Pressure { get; set; }
        public List<ErrorTemp> ErrorTemps { get; set; }
    }
    public class ErrorTemp
    {
        public string Temp { get; set; }
        public string Error { get; set; }
        public bool IsErrorOK { get; set; }
    }
}

我想根据IsErrorOK值更改单元格背景颜色。 我怎样才能在后面的代码中做到这一点?

如果事先知道 ErrorTemps 的最大数量,则跳过数据表并直接使用测量值

    <DataGrid ItemsSource="{Binding Measurements}" AutoGenerateColumns="False" CanUserAddRows="False" ColumnWidth="*">
        <DataGrid.Resources>
            <DataTemplate x:Key="ErrorTempTemplate" DataType="{x:Type local:ErrorTemp}">
                <TextBlock x:Name="txtError" Text="{Binding Error}" ToolTip="{Binding Temp}"/>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding IsErrorOK}" Value="false">
                        <Setter TargetName="txtError" Property="Background" Value="Red"/>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Address" Binding="{Binding Address}"/>
            <DataGridTextColumn Header="Pressure" Binding="{Binding Pressure}"/>
            <DataGridTemplateColumn Header="Temp1">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ContentControl Content="{Binding ErrorTemps[0]}" ContentTemplate="{StaticResource ErrorTempTemplate}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Temp2">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ContentControl Content="{Binding ErrorTemps[1]}" ContentTemplate="{StaticResource ErrorTempTemplate}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

如果它必须是完全动态的,这里有点混乱的解决方案

    <DataGrid x:Name="blubb" ItemsSource="{Binding Measurements}" AutoGenerateColumns="True" AutoGeneratingColumn="DataGrid_AutoGeneratingColumn" AutoGeneratedColumns="DataGrid_AutoGeneratedColumns" CanUserAddRows="False" ColumnWidth="*">
        <DataGrid.Resources>
            <Style x:Key="ErrorTempstyle" TargetType="DataGridCell">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Tag.IsErrorOK, RelativeSource={RelativeSource Self}}" Value="false">
                        <Setter Property="Background" Value="Red"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.Resources>
    </DataGrid>
        private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
        {
            e.Cancel = e.PropertyName == nameof(Measurement.ErrorTemps);
        }

        private void DataGrid_AutoGeneratedColumns(object sender, System.EventArgs e)
        {
            var datagrid = (DataGrid)sender;
            var firstItem = (Measurement)datagrid.Items[0];
            for (int i = 0; i < firstItem.ErrorTemps.Count; i++)
            {
                var s = new Style { TargetType = typeof(DataGridCell), BasedOn = (Style)datagrid.Resources["ErrorTempstyle"], Setters = { new Setter(TagProperty, new Binding($"ErrorTemps[{i}]")) } };
                datagrid.Columns.Add(new DataGridTextColumn { Header = firstItem.ErrorTemps[i].Temp, CellStyle = s, Binding = new Binding($"ErrorTemps[{i}].Error") });
            }
        }

如果我在 MainViewModel 构造函数中生成 Measurments,则第二个解决方案工作正常:

public MainViewModel()
    {
        OpenCommand = new DelegateCommand(OpenHandler);
        GenerateList();
    }

但是如果我要插入按钮,按下它后我会选择文本文件并生成测量值。 我使用按钮命令来做到这一点。:

主视图模型.cs:

 public class MainViewModel : BindableBase
{
    public ObservableCollection<Measurement> Measurements { get; set; } //= new ObservableCollection<Measurement>();
    public DelegateCommand OpenCommand { get; set; }
    public MainViewModel()
    {
        OpenCommand = new DelegateCommand(OpenHandler);
    }
    private void OpenHandler()
    {
        GenerateList();
    }
    private void GenerateList()
    {
        Measurements = new ObservableCollection<Measurement>()
        {
            new Measurement(){ Address="1", Pressure="10", ErrorTemps=new List<ErrorTemp>()
            {
                new ErrorTemp(){Temp="10", Error="0.1", IsErrorOK =true}, new ErrorTemp() { Temp = "20", Error = "0.2", IsErrorOK =true }, new ErrorTemp() { Temp = "30", Error = "0.41", IsErrorOK =true }}
            },
            new Measurement(){ Address="1", Pressure="20", ErrorTemps=new List<ErrorTemp>()
            {
                new ErrorTemp(){Temp="10", Error="0.2", IsErrorOK =true}, new ErrorTemp() { Temp = "20", Error = "0.3", IsErrorOK =true }, new ErrorTemp() { Temp = "30", Error = "0.42", IsErrorOK =true }}
            },
            new Measurement(){ Address="1", Pressure="30", ErrorTemps=new List<ErrorTemp>()
            {
                new ErrorTemp(){Temp="10", Error="0.34", IsErrorOK =true}, new ErrorTemp() { Temp = "20", Error = "0.5", IsErrorOK =false }, new ErrorTemp() { Temp = "30", Error = "0.43", IsErrorOK =false }}
            }
        };
    }

在上面的示例中,我简化了代码并在不选择文件的情况下生成了 Measurmenst 列表。 现在我有空的 DataGrid。 如何解决?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM