我有以下代码在运行时填充数据网格的资源。
DataTable dt = new DataTable();
dt.Columns.Add("Date");
dt.Columns.Add("User");
dt.Columns.Add("Type");
foreach (var x in query)
{
var row = dt.NewRow();
decimal total_REC = 0;
decimal total_RET = 0;
row["Date"] = x.CurrentDate.ToString();
row["User"] = x.User;
row["Type"] = x.TranscationType;
dt.Rows.Add(row);
}
最后,我将我的数据网格引用到此数据表
dgv_Transations.DataContext = dt;
在第一个函数中,我可以从x.TransactionType中找出需要突出显示哪些行。所有等于值“A”的类型将使其对应的行以黄色突出显示,因为在背景中将为黄色。
有没有办法以编程方式在运行时(从c#代码)设置整行的背景颜色为我想要的。我可以使用dt.rows.count作为我的索引,但我无法想出一种设置datagrid行背景颜色的方法(总是得到空引用异常)。
在winforms我会去datagridview.rows并继续,但在WPF我没有选项。我尝试了以下但它一直返回null。
if (dt.Rows.Count > 0)
{
DataGridRow r = dgv_Transations.ItemContainerGenerator.ContainerFromIndex(dt.Rows.Count - 1) as DataGridRow;
r.Background = Brushes.Red;
}
答案 0 :(得分:2)
我从一个稍微不同的解决方案中修改了这个答案。
您可以为拥有DataGrid的窗口创建XAML样式。
<Window.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Style.Setters>
<Setter Property="Background" Value="{Binding Path=Code}"></Setter>
</Style.Setters>
</Style>
</Window.Resources>
&#34;代码&#34;是类型为string的类变量的名称,它包含颜色名称(&#34;红色&#34;,&#34;蓝色&#34;等)。所以在你的情况下&#34; Code&#34;将是你的dt中的一个专栏。
然后,你需要设置&#34; Code&#34;的值。只要你想要突出显示这条线就黄色。
如果您不是很清楚,请参阅我在此处使用的原始代码示例:
答案 1 :(得分:0)
您可以创建一个将事务类型转换为画笔的IValueConverter 并在Window.Resources中输入一个条目进行注册。
public class TransactionTypeConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var trxnType = value as int;
if (value == null || trxnType==null) return Brushes.Transparent;
if(trxnType==1) return Brushes.Red;
return Brushes.Transparent;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
}
然后你可以尝试两件事:
您可以将DataGrid的RowBackground绑定到Type并将Converter绑定到TransactionTypeConverter:
&lt; DataGrid RowBackground =&#34; {Binding transactionType}&#34; Converter =&#34; {StaticResource TransactionTypeConverter}&#34;&gt;
在细胞模板中做同样的事情。
答案 2 :(得分:0)
执行此操作的常见和推荐方法是使用@Sach建议的XAML中的数据触发器,但如果您仍希望以编程方式执行此操作,则实际上可以使用{{1}获取对可视容器的引用}。
您必须等到创建容器。您可以通过调用ItemContainerGenerator
事件处理程序中的ContainerFromIndex
方法来执行此操作:
Loaded
第二个问题是DataGrid使用UI虚拟化。这意味着只生成您在屏幕上实际看到的数据行的容器。因此,如果最后一行被滚动,它就不再有任何DataGridRow容器。
您可以通过禁用虚拟化来解决此问题:
public MainWindow()
{
InitializeComponent();
DataTable dt = new DataTable();
dt.Columns.Add("Date");
dt.Columns.Add("User");
dt.Columns.Add("Type");
for (int i = 1; i < 10; ++i)
{
var row = dt.NewRow();
row["Date"] = 1;
row["User"] = 2;
row["Type"] = 3;
dt.Rows.Add(row);
}
dgv_Transations.ItemsSource = dt.DefaultView;
dgv_Transations.Loaded += (s, e) =>
{
if (dt.Rows.Count > 0)
{
DataGridRow r = dgv_Transations.ItemContainerGenerator.ContainerFromIndex(dt.Rows.Count - 1) as DataGridRow;
r.Background = Brushes.Red;
}
};
}
当然这可能会对性能产生负面影响。
另一个选项是滚动到该项目,然后以编程方式生成容器:
<DataGrid x:Name="dgv_Transations" VirtualizingPanel.IsVirtualizing="False" />