如何在以编程方式添加DataTrigger时继承WPF DataGrid单元格样式?
如何在以编程方式添加DataTrigger时继承WPF DataGrid单元格样式?
我正在编写一个使用DataGrid控件的WPF应用程序。我正在使用MaterialDesign主题来为应用程序添加样式,这使其看起来很漂亮。
然而,由于某种复杂的原因,我需要以编程方式将列添加到dataGrid中。对于其中一些列,我还在对列进行样式设置,以突出显示通过/失败为红色。但是当我这样做时,我会失去Material Design为该列提供的一些样式,即水平和垂直对齐。
上面的代码如下所示:
// 定义Setter
Setter setterResultFail = new Setter();
setterResultFail.Property = DataGridCell.BackgroundProperty;
setterResultFail.Value = Brushes.Red;
// 创建一个用于站点的列。
var currentColumn = new DataGridTextColumn();
currentColumn.Header = "设备号";
currentColumn.Binding = new Binding("Device");
ResultsDataGrid.Columns.Add(currentColumn);
// 创建一个用于站点的列。
currentColumn = new DataGridTextColumn();
currentColumn.Header = "站点";
currentColumn.Binding = new Binding("Site");
ResultsDataGrid.Columns.Add(currentColumn);
// 创建一个用于通过失败的列。
currentColumn = new DataGridTextColumn();
currentColumn.Header = "通过失败";
currentColumn.Binding = new Binding("PassFail") { Converter = new BooleanToPassFailConverter() };
// 创建一个单元格样式,当PassFail值为False时,使单元格变为“红色”(通过数据触发器实现)
cellStyle = new Style(typeof(DataGridCell));
// 定义第一个数据触发器,如果值为失败,则将单元格设置为红色。
dataTrigger = new DataTrigger();
dataTrigger.Value = "False";
dataTrigger.Binding = new Binding("PassFail");
dataTrigger.Setters.Add(setterResultFail);
// 将数据触发器添加到单元格样式中。
cellStyle.Triggers.Clear();
cellStyle.Triggers.Add(dataTrigger);
// 应用新创建的单元格样式。
currentColumn.CellStyle = cellStyle;
ResultsDataGrid.Columns.Add(currentColumn);
显然,新的cellStyle被用来替代MaterialDesign样式。我尝试手动设置垂直/水平的值,但无法正确显示:
Setter setterTextContentHorizonalAlignment = new Setter();
setterTextContentHorizonalAlignment.Property = DataGridCell.HorizontalContentAlignmentProperty;
setterTextContentHorizonalAlignment.Value = HorizontalAlignment.Center;
Setter setterTextContentVerticalAlignment = new Setter();
setterTextContentVerticalAlignment.Property = DataGridCell.VerticalContentAlignmentProperty;
setterTextContentVerticalAlignment.Value = VerticalAlignment.Center;
Setter setterTextHorizontalAlignment = new Setter();
setterTextHorizontalAlignment.Property = DataGridCell.HorizontalAlignmentProperty;
setterTextHorizontalAlignment.Value = HorizontalAlignment.Center;
Setter setterTextVerticalAlignment = new Setter();
setterTextVerticalAlignment.Property = DataGridCell.VerticalAlignmentProperty;
setterTextVerticalAlignment.Value = VerticalAlignment.Center;
cellStyle.Setters.Add(setterTextContentHorizonalAlignment);
cellStyle.Setters.Add(setterTextContentVerticalAlignment);
cellStyle.Setters.Add(setterTextHorizontalAlignment);
cellStyle.Setters.Add(setterTextVerticalAlignment);
是否有一种方法可以添加到样式中而不是替换它...类似于XAML中的BasedOn方法?
问题出现的原因是在以编程方式添加DataTrigger时,无法继承WPF DataGrid单元格样式。解决方法是使用Danny Beckett和King King的答案,在特定的单元格上应用解决方案。
具体解决方法如下:
1. 创建一个用于“Pass Fail”列的DataGridTextColumn,并设置Header和Binding属性。
currentColumn = new DataGridTextColumn(); currentColumn.Header = "Pass Fail"; currentColumn.Binding = new Binding("PassFail") { Converter = new BooleanToPassFailConverter() };
2. 创建一个CellStyle来使单元格在PassFail值为False时变为红色(通过DataTrigger实现)。
cellStyle = new Style(typeof(DataGridCell)); dataTrigger = new DataTrigger(); dataTrigger.Value = "False"; dataTrigger.Binding = new Binding("PassFail"); dataTrigger.Setters.Add(setterResultFail); cellStyle.Triggers.Clear(); cellStyle.Triggers.Add(dataTrigger);
3. 创建一个ControlTemplate并定义样式。
var border = new FrameworkElementFactory(typeof(Border)); border.SetBinding(Border.BorderBrushProperty, new Binding("BorderBrush") { RelativeSource = RelativeSource.TemplatedParent }); border.SetBinding(Border.BackgroundProperty, new Binding("Background") { RelativeSource = RelativeSource.TemplatedParent }); border.SetBinding(Border.BorderThicknessProperty, new Binding("BorderThickness") { RelativeSource = RelativeSource.TemplatedParent }); border.SetValue(SnapsToDevicePixelsProperty, true); var contentPresenter = new FrameworkElementFactory(typeof(ContentPresenter)); contentPresenter.SetBinding(SnapsToDevicePixelsProperty, new Binding("SnapsToDevicePixelsProperty") { RelativeSource = RelativeSource.TemplatedParent }); contentPresenter.SetBinding(VerticalAlignmentProperty, new Binding("VerticalContentAlignment") { RelativeSource = RelativeSource.TemplatedParent }); contentPresenter.SetBinding(HorizontalAlignmentProperty, new Binding("HorizontalContentAlignment") { RelativeSource = RelativeSource.TemplatedParent }); border.AppendChild(contentPresenter); var template = new ControlTemplate(typeof(DataGridCell)); template.VisualTree = border;
4. 在CellStyle中添加Setter,将ControlTemplate应用于单元格,并设置VerticalContentAlignmentProperty和HorizontalContentAlignmentProperty属性。
cellStyle.Setters.Add(new Setter(TemplateProperty, template)); cellStyle.Setters.Add(new Setter(VerticalContentAlignmentProperty, VerticalAlignment.Center)); cellStyle.Setters.Add(new Setter(HorizontalContentAlignmentProperty, HorizontalAlignment.Center));
5. 应用新创建的CellStyle。
currentColumn.CellStyle = cellStyle;
通过以上步骤,可以解决以编程方式添加DataTrigger时无法继承WPF DataGrid单元格样式的问题。