代码中的WPF数据表格样式

3

我在我的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") - Louis Kottmann
BorderBrushProperty.OverrideMetadata(typeof(DionysusDataGrid), new FrameworkPropertyMetadata((Color)ColorConverter.ConvertFromString("#FFDDDDDD"))); 给出同样的错误。 - Chrisjan Lodewyks
确保您在使用Color类型时使用正确的命名空间,并将其与BorderBrush的类型进行比较。 - Louis Kottmann
@狒狒来帮忙了。检查我的更新以获取正确的代码。现在要在代码中设置行样式! - Chrisjan Lodewyks
1个回答

7

如果要在代码后端中设置样式,需要遵循一些通用规则:

XAML中输入的任何内容都有其C#等效语法。

<Style ...>System.Windows.Style相同。其他如SetterTrigger等也是一样。

唯一要注意的是ContentProperty属性,它是默认属性,例如当你执行以下操作时:

<TextBlock>My text here!</TextBlock>

这段代码将TextBlock.Text属性设置为"My text here!",因为TextBlock类被标记为带有属性[ContentProperty("Text")]

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

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

Becomes:

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? - Chrisjan Lodewyks
@ChrisjanL 我的谷歌搜索找到了这个链接:http://www.codeproject.com/Tips/240670/WPF-TemplateBinding-in-code 。我想应该可以正常工作。 - Louis Kottmann
经典的过度思考简单解决方案的案例。我在资源字典中有这个样式,可以简单地使用“this.Style = Application.Current.Resources[typeof(DataGrid)] as Style;”。但感谢所有的帮助,如果我需要从代码后台设置样式,我现在有一个更好的想法! - Chrisjan Lodewyks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接