簡體   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