【问题标题】:Trying to apply multiple styles to a DataGridRow尝试将多种样式应用于 DataGridRow
【发布时间】:2016-03-31 22:12:50
【问题描述】:

我有 WPF 应用程序,我在 App.xaml 中创建了 DataGrid 样式以应用整个应用程序。

App.xaml

<Style TargetType="DataGrid" x:Key="GridStyle1">
    <Setter Property="HorizontalGridLinesBrush" Value="LightGray" />
    <Setter Property="VerticalGridLinesBrush" Value="LightGray" />
    <Setter Property="AlternatingRowBackground" Value="WhiteSmoke" />
    <Setter Property="RowHeight" Value="30" />
    <Setter Property="RowStyle">
        <Setter.Value>
            <Style TargetType="DataGridRow">
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Background" Value="Cyan" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Setter.Value>
    </Setter>
</Style>

然后在窗口中:

window1.xaml

<Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
    <Setter Property="FontStyle" Value="Italic" />
</Style>

窗口样式不适用的问题(字体样式不是斜体)

【问题讨论】:

  • 如果您实际上将GridStyle1 应用于您的DataGrid,那么该样式就是在DataGrid 中设置DataGridRow 的样式,您创建的默认样式当然是忽略。您的DataGridRows 是否以青色背景出现?尝试将相同的BasedOn 属性添加到设置青色背景的样式中。这可能是实际使用的那个。可能还有其他问题,但请先尝试。
  • 我尝试将相同的 BaseOn 属性添加到青色背景,但它没有用,我得到相同的结果,(应用了青色背景,但 FontStyle 不是斜体)。
  • 你也添加了字体样式吗?
  • 我只想从 Window1 应用 Fontstyle 而不是整个应用程序,这就是我在 Window1 中添加它的原因
  • 我面前没有你所有的代码,所以我猜不出你想做什么。如果您希望 Window1 中的数据网格为斜体,请设置直接在 Window1 中的该网格上执行此操作的 RowStyle。您不必使用 DataGrid 样式来做所有事情。

标签: c# wpf


【解决方案1】:

看起来您想对多个窗口中的每个DataGrid 中的每个DataGridRow 应用全局样式,并且您还想在一个或多个窗口中为DataGridRow 应用附加样式DataGrids 在一个特定的窗口中。

如果你以前学过 CSS,你可能会期望样式表是累积的:在 CSS 中,如果你全局应用 tr.style1 和本地应用 tr.style2,你会得到两者,tr.style2 在任何情况下都会赢得折腾他们设置了相同的属性。

这不是 XAML 中样式的工作方式。 在 XAML 中,一个元素可以从其父元素继承样式,但它最多可以有一个自己的 Style。此外,正如您所发现的,Style 有一个 BasedOn 属性。您可以将一种风格建立在另一种风格的基础上,并获得两者的累积效果。

最后,有几种方法可以应用样式。您发现可以将它们应用于给定范围内给定类型的每个元素。

不幸的是,因为一切都取决于上下文,所以应用 XAML 样式的方式一开始可能会非常混乱(然后是第二个,有时是第三个)。特别是当您使用一种样式 (GridStyle1) 来应用另一种样式时。什么覆盖什么并不总是很明显。

最好让事情尽可能简单。我们将摆脱那个RowStyle setter,因为我们不需要它。我们将只创建一个全局DataGridRowStyle,默认情况下它适用于每个DataGridRow,然后我们将在window1.xaml 中专门覆盖它。

App.xaml

<Application.Resources>
    <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
        <Setter Property="Background" Value="Cyan" />
    </Style>
</Application.Resources>

window1.xaml

<Window.Resources>
    <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
        <Setter Property="FontStyle" Value="Italic" />
    </Style>
</Window.Resources>

这将适用于该窗口中的每个DataGridRow。那里的BasedOn 属性将引用在任何包含上下文中已经为DataGridRow 定义的任何样式——通常,这意味着App.xaml,如果我们不添加任何其他内容,这里就是这种情况.

这与您所拥有的不同之处在于您以不同的方式应用青色 Background 样式:您在 App.xaml 中应用的 DataGridRow 样式是通过您的 @987654344 上的 RowStyle 设置器应用的@ 风格。该样式是BasedOn WPF 预先存在的DataGridRow 的默认Style,然后它被强制应用于使用GridStyle1 样式的每个DataGrid 中的每个DataGridRow

如果DataGrid.RowStyle 尚未在GridStyle1 中设置,您在window1.xaml 中定义的DataGridRow 样式 已应用。

但正如我们所见,您不需要使用 RowStyle 将样式全局应用于每个 DataGridRow。您可以使用该类型的默认样式来执行此操作,如上面我的 App.xaml 片段中所示。 DataGrid.RowStyle 对于单独在一个特定的DataGrid 上覆盖全局DataGridRow 样式很有用。但是你不想在全球范围内这样做!所以你在 App.xaml 中的样式应该是这样的:

App.xaml

<Style TargetType="DataGrid" x:Key="GridStyle1">
    <Setter Property="HorizontalGridLinesBrush" Value="LightGray" />
    <Setter Property="VerticalGridLinesBrush" Value="LightGray" />
    <Setter Property="AlternatingRowBackground" Value="WhiteSmoke" />
    <Setter Property="RowHeight" Value="30" />
</Style>

<Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
    <Setter Property="Background" Value="Cyan" />
</Style>

再一次,这是 window1.xaml

中的 Style
<Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
    <Setter Property="FontStyle" Value="Italic" />
</Style>

额外积分

上面的样式应该可以解决您的问题。

但是还有其他方法可以处理这些东西。除非你对我们上面所做的很满意,否则接下来的内容可能只会增加混乱,所以如果你开始阅读这篇文章,你发现你阅读的越多,你理解的越少——那就停止阅读吧!它可以等待!

您还可以将 DataGrid 中的所有文本设置为斜体,但这也会更改标题,所以我认为这不是您想要的:

<DataGrid 
    FontStyle="Italic"
    />

如果您只想在 window1.xaml 中的一个网格上应用 Italic 样式,请按以下步骤操作。如果我们将x:Key 属性添加到Style,它将不会应用于范围内的每个DataGridRow。相反,它只是坐在那里,等待被用作StaticResource 的名称。

window1.xaml

<Window.Resources>
    <Style x:Key="ItalicDataGridRowStyle" 
           TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
        <Setter Property="FontStyle" Value="Italic" />
    </Style>
</Window.Resources>

<-- ... -->

<!-- One grid with italic rows -->
<DataGrid
    x:Name="dataGrid1"
    RowStyle="{StaticResource ItalicDataGridRowStyle}"
    />

<!-- And another grid with default rows -->
<DataGrid
    x:Name="dataGrid2"
    />

这是另一种将样式应用于 window1.xaml 中一个网格中的行的方法:

<!-- Yet another grid -->
<DataGrid
    x:Name="dataGrid3"
    >
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow" BasedOn="{StaticResource ItalicDataGridRowStyle}">
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="Background" Value="Wheat" />
        </Style>
    </DataGrid.RowStyle>
</DataGrid>

最后,您可以GridStyle1 中设置RowStyle,然后在特定窗口中的特定网格上显式设置RowStyle,如上所述。那会奏效。您还可以在 window1.xaml 中创建一个新的DataGrid 样式(基于GridStyle1),将RowStyle 设置为其他内容。

【讨论】:

    猜你喜欢
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 2020-08-20
    • 2020-04-04
    • 1970-01-01
    • 2013-12-07
    • 2021-05-20
    • 1970-01-01
    相关资源
    最近更新 更多