[英]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.