应用WPF样式类似于CSS和HTML

5
我不确定是否可能,但只是想确认一下。
我正在编写一个简单的WPF应用程序,并希望定义外部样式,因此您可以将样式作为外部资源加载。有点类似于通常将CSS和HTML分离...
然而,有一件事情让我困扰,那就是在HTML和CSS中它更像是一种从外部向内部的方法,CSS会针对元素并应用于匹配元素。但是在WPF中,似乎是相反的,您必须告诉元素应该应用哪些样式,但这似乎不太动态。所以我想知道是否有一种方式,可以应用样式,使得样式仅针对元素。
例如:
<Style TargetType="{x:Type TextBox}" TargetElement="{x:Name SomeTextboxElement}">
    <Setter Property="Width" Value="Auto"/>
</Style>

通常情况下,您需要为样式指定一个键,然后获取要映射到该样式键的元素(SomeTextboxElement)。
但是,必须明确地为每个元素提供样式绑定,这似乎有点愚蠢,它应该更具层次结构,并向下过滤(可能是可能的,我只是不知道如何实现),而不是一对一映射。整个应用程序的样式化将需要很长时间...
希望这能让人理解...
3个回答

2

您所说的内容很有趣,但不符合wpf的思维方式。在wpf中,您可以将样式应用于可视化元素或可视化元素的类型(即:您可以将样式应用于某种类型,或者定义一个具有命名键的资源样式,并明确使用该键)。对于您的情况,我认为创建以下样式应该就可以:

<Style TargetType="{x:Type TextBox}">
   <Setter Property="Width" Value="Auto"/>
</Style>

这会将你的样式应用于所有文本框,只需省略TargetElement属性。

我知道这不完全相同,但如果您想要相同的基本控件样式,只需根据使用情况进行一些小改变,您可以尝试使用触发器对其进行微小更改。 我通常使用我的控件的“Tag”属性为样式定义提供一些额外的信息。 以下是一个基本按钮样式示例,但有3个按钮:

        <Style.Triggers>
            <Trigger Property="Tag" Value="delete">
                <Setter Property="Background" Value="Red"></Setter>
            </Trigger>
            <Trigger Property="Tag" Value="confirm">
                <Setter Property="Background" Value="Green"></Setter>
            </Trigger>
        </Style.Triggers>

现在有一些假设。如果满足以下两个条件,您想要的将非常容易实现:
  • 所有WPF可视化元素都有一个名为“ParentVisual”的DependencyProperty,返回直接包含该可视化元素的可视化元素。
  • 所有WPF可视化元素都有一个DepencyProperty,例如“VisualType”

如果满足以上条件,并结合触发器/多触发器,则可以创建针对ParentVisual.VisualType的触发器。

让我们定义一些假想的CSS样式,以便WPF将其应用于包含在网格中的ID为“subnavi”的边框内的任何TextBox。

Grid Border#subnavi TextBox
{
    backgroundColor:#FF0000;
}

在 WPF 中进行翻译,这将是一个具有三个条件的 TextBox 的多触发器:
  <MultiTrigger>
   <Condition Property="ParentVisual.VisualType" Value="Border"></Condition>
   <Condition Property="ParentVisual.Name" Value="subnavi"></Condition>
   <Condition Property="ParentVisual.ParentVisual.VisualType" Value="Grid"></Condition>
   <Setter Property="Background" Value="Red"/>
  </MultiTrigger>

不幸的是,没有这样的DependencyProperties,因此如果您为每个wpf控件创建包装器,那么您只能使用我上面提到的机制。

回到我所说的WPF思维方式:WPF元素通过WPF引擎沿着可视化树向上(而不是向下)进行样式设置,从问题控件开始。我认为CSS是相反的。

编辑:我认为在上面写的内容中使用DependencyObject类可能更加明智,而不是使用Visual。


很遗憾,因为WPF似乎正在弥合Web开发人员和应用程序开发人员之间的差距,不过给每个对象指定一个显式样式名称并不是世界末日,因为它仍然可以被覆盖,但是在将来维护和更改时似乎需要更多的工作。 - somemvcperson

1

0
你正在寻找隐式样式。它们没有 CSS 选择器那么细致,但您可以为每种类型的元素定义一个样式。例如,下面的示例表示:“我希望所有按钮的宽度为80”。
<Style TargetType="{x:Type Button}">
    <Setter Property="Width" Value="80"/>
</Style>

这些定义可以在多个不同的范围内完成:应用程序、页面、控件或任何框架元素,只需将其添加为资源即可。运行时将采用自下而上的方法搜索隐式样式,并使用它找到的第一个样式。

请查看本文以获取更多详细信息。


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