【发布时间】:2015-12-17 05:22:35
【问题描述】:
我们如何在 WPF 数据网格中以编程方式为单元格添加颜色?我可以逐行添加颜色,但我想从后面的代码为单元格添加颜色。请提供代码?
【问题讨论】:
我们如何在 WPF 数据网格中以编程方式为单元格添加颜色?我可以逐行添加颜色,但我想从后面的代码为单元格添加颜色。请提供代码?
【问题讨论】:
此代码的作用:首先,您处理LoadingRow 事件,获取行(它具有保存绑定项目的 Item 属性),获取绑定项目,进行所有需要的计算,获取您需要的单元格改变并最终改变目标单元格的样式。
这是代码(作为项目,我使用带有 int ID 属性的示例对象,用于着色)。:
C#:
private void FillTheDataGrid()
{
List<SomeClass> list = new List<SomeClass>();
Random rnd = new Random();
for (int i = 0; i < 10; i++)
{
list.Add(new SomeClass() { DaysOld = DateTime.Now.Add(new TimeSpan(rnd.Next(5), 0, 0, 0)), ID=i});
}
dataGrid.ItemsSource = list;
}
private void dataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() => AlterRow(e)));
}
private void AlterRow(DataGridRowEventArgs e)
{
var cell = GetCell(dataGrid, e.Row, 1);
if (cell == null) return;
var item = e.Row.Item as SomeClass;
if (item == null) return;
var value = item.ID;
if (value <= 1) cell.Background = Brushes.Red;
else if (value <= 2) cell.Background = Brushes.Yellow;
else cell.Background = Brushes.Green;
}
public static DataGridRow GetRow(DataGrid grid, int index)
{
var row = grid.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow;
if (row == null)
{
// may be virtualized, bring into view and try again
grid.ScrollIntoView(grid.Items[index]);
row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
public static T GetVisualChild<T>(Visual parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
var v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T ?? GetVisualChild<T>(v);
if (child != null)
{
break;
}
}
return child;
}
public static DataGridCell GetCell(DataGrid host, DataGridRow row, int columnIndex)
{
if (row == null) return null;
var presenter = GetVisualChild<DataGridCellsPresenter>(row);
if (presenter == null) return null;
// try to get the cell but it may possibly be virtualized
var cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
if (cell == null)
{
// now try to bring into view and retreive the cell
host.ScrollIntoView(row, host.Columns[columnIndex]);
cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
}
return cell;
}
型号:
public class SomeClass
{
public int ID { get; set; }
public DateTime DaysOld { get; set; }
}
XAML:
<DataGrid Name="dataGrid" AutoGenerateColumns="True" LoadingRow="dataGrid_LoadingRow"/>
【讨论】:
我遇到了同样的问题,终于找到了答案,比我想象的要容易,这里是更改单元格颜色的代码:
DataGridRow firstRow = dataGrid.ItemContainerGenerator.ContainerFromItem(dataGrid.Items[i]) as DataGridRow;
firstColumnInFirstRow = dataGrid.Columns[j].GetCellContent(firstRow).Parent as DataGridCell;
firstColumnInFirstRow.Background = Brushes.IndianRed;
【讨论】:
根据 DataGridCell 中的内容,您可以创建一个绑定到颜色或使用触发器的 DataTemplate
<DataTemplate DataType="{x:Type cell:MyCellObject}">
<TextBlock TextAlignment="Center" Text="{Binding Text}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Background" Value="{Binding MyBackground}" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Padding" Value="0" />
<Style.Triggers>
<DataTrigger Binding="{Binding MyBool}" Value="True">
<Setter Property="Foreground" Value="DarkRed" />
<Setter Property="FontWeight" Value="Bold" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
【讨论】: