【问题标题】:How do I Inherit a WPF DataGrid Cell Style when programmatically adding a DataTrigger?以编程方式添加 DataTrigger 时如何继承 WPF DataGrid 单元格样式?
【发布时间】:2018-08-21 19:50:29
【问题描述】:

我正在编写一个使用 DataGrid 控件的 WPF 应用程序。我正在使用 MaterialDesign 主题来设置应用程序的样式,这给人一种很好的外观和感觉。

但是,由于复杂的原因,我不会在这里介绍,我需要以编程方式将列添加到 dataGrid 中。对于某些列,我还设置了列的样式,以红色突出显示通过/失败。当我这样做时,我失去了材料设计为该列提供的“一些样式”。即水平和垂直对齐方式。

上面的代码如下:

            // Define Setter
            Setter setterResultFail = new Setter();
            setterResultFail.Property = DataGridCell.BackgroundProperty;
            setterResultFail.Value = Brushes.Red;

            // Create a column for the Site.
            var currentColumn = new DataGridTextColumn();
            currentColumn.Header = "Device #";
            currentColumn.Binding = new Binding("Device");
            ResultsDataGrid.Columns.Add(currentColumn);

            // Create a column for the Site.
            currentColumn = new DataGridTextColumn();
            currentColumn.Header = "Site";
            currentColumn.Binding = new Binding("Site");
            ResultsDataGrid.Columns.Add(currentColumn);

            // Create a column for the Pass Fail.
            currentColumn = new DataGridTextColumn();
            currentColumn.Header = "Pass Fail";
            currentColumn.Binding = new Binding("PassFail") { Converter = new BooleanToPassFailConverter() };

            // Create cellstyle to make the cell 'red' when the PassFail value is False. ( this is done via a data trigger )
            cellStyle = new Style(typeof(DataGridCell));

            // Define First DataTrigger that sets a CELL red if the value is a fail.
            dataTrigger = new DataTrigger();
            dataTrigger.Value = "False";
            dataTrigger.Binding = new Binding("PassFail");            
            dataTrigger.Setters.Add(setterResultFail);

            // Add the data-triggers to the cell style.
            cellStyle.Triggers.Clear();
            cellStyle.Triggers.Add(dataTrigger);

            // Apply the newly created cell style.
            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 方法?

【问题讨论】:

    标签: c# wpf material-design wpfdatagrid


    【解决方案1】:

    在这个问题上浪费了很多时间后,我遇到了 Danny Beckett 的类似问题和 King King 的回答。通过使用他的答案并将其应用于特定的单元格,我遇到了问题解决了这个问题:King King's answer

         // Create a column for the Pass Fail.
         currentColumn = new DataGridTextColumn();
         currentColumn.Header = "Pass Fail";
         currentColumn.Binding = new Binding("PassFail") { Converter = new BooleanToPassFailConverter() };
    
         // Create cellstyle to make the cell 'red' when the PassFail value is False. ( this is done via a data trigger )
         cellStyle = new Style(typeof(DataGridCell));
    
         // Define First DataTrigger that sets a CELL red if the value is a fail.
         dataTrigger = new DataTrigger();
         dataTrigger.Value = "False";
         dataTrigger.Binding = new Binding("PassFail");
         dataTrigger.Setters.Add(setterResultFail);
    
         // Add the data-triggers to the cell style.
         cellStyle.Triggers.Clear();
         cellStyle.Triggers.Add(dataTrigger);
    
         //root visual of the ControlTemplate for DataGridCell is a Border
         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);
    
         //the only child visual of the border is the ContentPresenter
         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 });
         //add the child visual to the root visual
         border.AppendChild(contentPresenter);
    
         //here is the instance of ControlTemplate for DataGridCell
         var template = new ControlTemplate(typeof(DataGridCell));
         template.VisualTree = border;
    
         //define the style
         cellStyle.Setters.Add(new Setter(TemplateProperty, template));
         cellStyle.Setters.Add(new Setter(VerticalContentAlignmentProperty, VerticalAlignment.Center));
         cellStyle.Setters.Add(new Setter(HorizontalContentAlignmentProperty, HorizontalAlignment.Center));
    
         // Apply the newly created cell style.
         currentColumn.CellStyle = cellStyle;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-26
      • 2022-01-04
      • 2010-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多