【问题标题】:WPF DataGrid Style in code behind代码中的 WPF DataGrid 样式
【发布时间】:2012-10-24 20:13:00
【问题描述】:

我的 WPF 应用程序中有一个用于数据网格的 xaml 样式,我现在正在编写一个继承自 DataGrid 的自定义控件,并希望在后面的代码中应用以下样式:

<Style TargetType="DataGrid">

    <!-- Make the border and grid lines a little less imposing -->
    <Setter Property="BorderBrush" Value="#DDDDDD" />
    <Setter Property="HorizontalGridLinesBrush" Value="#DDDDDD" />
    <Setter Property="VerticalGridLinesBrush" Value="#DDDDDD" />

    <Setter Property="RowStyle">
        <Setter.Value>
            <Style TargetType="DataGridRow">
                <Style.Triggers>
                    <!-- Highlight a grid row as the mouse passes over -->
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="Lavender" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Setter.Value>
    </Setter>
    <Setter Property="CellStyle">
        <Setter.Value>
            <Style TargetType="DataGridCell">
                <Style.Triggers>
                    <!-- Highlight selected rows -->
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Background" Value="Lavender" />
                        <Setter Property="BorderBrush" Value="Lavender" />
                        <Setter Property="Foreground" Value="Black" />
                    </Trigger>
                    <!--StartsEditingOnMouseOver-->
                    <!--<Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="IsEditing" Value="True" />
                    </Trigger>-->
                </Style.Triggers>

                <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown" />
                <EventSetter Event="PreviewTextInput" Handler="DataGridCell_PreviewTextInput" />

                <!-- Add some padding around the contents of a cell -->
                <Setter Property="Padding" Value="4,3,4,3" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="DataGridCell">
                            <Border Padding="{TemplateBinding Padding}" 
                            Background="{TemplateBinding Background}">
                                <ContentPresenter />
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
</Style>

到目前为止,我有以下代码:

static DionysusDataGrid()
{

  BorderBrushProperty.OverrideMetadata(typeof(DionysusDataGrid), new FrameworkPropertyMetadata(ColorConverter.ConvertFromString("#FFDDDDDD") as Color?));
  HorizontalGridLinesBrushProperty.OverrideMetadata(typeof(DionysusDataGrid), new FrameworkPropertyMetadata(ColorConverter.ConvertFromString("#FFDDDDDD") as Color?));
  VerticalGridLinesBrushProperty.OverrideMetadata(typeof(DionysusDataGrid), new FrameworkPropertyMetadata(ColorConverter.ConvertFromString("#FFDDDDDD") as Color?));

}

但我不知道如何对本身也有样式的“RowStyle”属性做同样的事情。而且我在设置 BorderBrushProperty 时也收到以下错误:

Default value type does not match type of property 'BorderBrush'."

谁能帮帮我?

感谢

更新:

我通过将代码更新为以下内容解决了错误:

    static DionysusDataGrid()
{

  BrushConverter converter = new BrushConverter();

  BorderBrushProperty.OverrideMetadata(typeof(DionysusDataGrid), new FrameworkPropertyMetadata((System.Windows.Media.Brush)converter.ConvertFromString("#FFDDDDDD")));
  HorizontalGridLinesBrushProperty.OverrideMetadata(typeof(DionysusDataGrid), new FrameworkPropertyMetadata((System.Windows.Media.Brush)converter.ConvertFromString("#FFDDDDDD")));
  VerticalGridLinesBrushProperty.OverrideMetadata(typeof(DionysusDataGrid), new FrameworkPropertyMetadata((System.Windows.Media.Brush)converter.ConvertFromString("#FFDDDDDD")));

}

【问题讨论】:

  • 您是否尝试将常规强制转换为不可为空的 Color ?即:(Color)ColorConverter.ConvertFromString("#FFDDDDDD")
  • BorderBrushProperty.OverrideMetadata(typeof(DionysusDataGrid), new FrameworkPropertyMetadata((Color)ColorConverter.ConvertFromString("#FFDDDDDD")));给出同样的错误。
  • 确保为 Color 类型使用正确的命名空间,并根据 BorderBrush 的类型对其进行检查。
  • @Baboon 来救援。检查我的更新以获取正确的代码。现在在代码中做行样式!

标签: c# wpf xaml


【解决方案1】:

要在代码中创建样式,需要遵循一些通用规则:

您在 XAML 中键入的任何内容在古老的 C# 中都有等效项:

&lt;Style ...&gt; 只是System.Windows.StyleSetterTrigger 也是如此。

唯一的问题来自ContentProperty 属性,这是分配的默认属性,例如当您这样做时:

<TextBlock>My text here!</TextBlock>

它将TextBlock.Text 属性设置为"My text here!",因为TextBlock 类标有[ContentProperty("Text")] 属性

最后,当你从 C# 构建时,你需要从最嵌套的元素开始:

<Style TargetType="DataGrid">
    <Setter Property="BorderBrush" Value="#DDDDDD" />
</Style>

变成:

var brushConverter = new BrushConverter();

var bbSetter = new Setter(
    DataGrid.BorderBrushProperty, 
    brushConverter.ConvertFromString("#FFDDDDDD"));

var style = new Style(typeof(DataGrid));    
style.Setters.Add(bbSetter);

从此您应该能够将任何 XAML 转换为 C#,
不过,请注意,您不能将任何 C# 映射到 XAML,例如,您不能在 XAML 中制作动态故事板,但您可以在 C# 中。

【讨论】:

  • 非常感谢@Baboon!这有帮助......我已经完成了大部分工作并且现在正在工作,我唯一苦苦挣扎的部分是 DataGridCell 的模板。 TemplateBinding如何在代码中完成?
  • @ChrisjanL 我的谷歌搜索发现:codeproject.com/Tips/240670/WPF-TemplateBinding-in-code。我猜应该可以正常工作。
  • 过度思考简单解决方案的经典案例。我在资源字典中有这种样式,可以简单地使用“this.Style = Application.Current.Resources[typeof(DataGrid)] as Style;”。但是感谢所有帮助,如果我确实需要从后面的代码中设置样式,我会更好地了解如何做到这一点!
猜你喜欢
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
  • 2016-01-03
  • 1970-01-01
  • 1970-01-01
  • 2011-05-31
  • 2013-03-10
相关资源
最近更新 更多