应用WPF样式,如CSS和Html



我怀疑这是可能的,但只是想确认一下。

我正在编写一个简单的WPF应用程序,并希望我的样式在外部定义,所以你基本上可以将样式作为外部资源加载。这有点像CSS和HTML通常是如何分开的…

然而,有一件事让我很困扰,那就是HTML &CSS更多的是一种向外看的方法,CSS针对元素并应用于匹配元素。然而,在WPF中,它似乎是另一种方式,你必须告诉元素它应该应用什么样式,然而这似乎不是很动态。所以我只是想知道是否有一种方法可以应用样式,使样式只针对元素。

一个例子是:

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

通常你必须指定一个键与样式,然后得到元素(SomeTextboxElement)映射到样式的键。

这似乎有点傻,必须显式地给每个元素一个样式绑定,它应该更分层和过滤(这可能是可能的,我只是不知道如何),而不是一个一对一的映射。给整个应用程序设计样式会花很长时间…

你说你正在寻找的是有趣的,但与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"

考虑到这一点,并将其与触发器/multi触发器相结合,然后让您为ParentVisual.VisualType创建触发器。

让我们为WPF定义一些假设的CSS,以将样式应用于包含在边框内的任何文本框,Id为"subnavi",包含在网格中。

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

翻译成WPF,这将是一个具有三个条件的文本框的Multitrigger:

  <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更明智。

我不知道你是否还想这样做,但是Colin Eberhardt之前做了一些事情:http://www.codeproject.com/Articles/36499/Using-CSS-Selectors-for-Styling-in-WPF

您正在寻找隐式样式。它们不像css选择器那样细粒度,但是您可以为每种类型的元素定义样式。例如,下面的例子说:"我想让我所有的按钮的宽度为80"

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

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

最新更新