我怀疑这是可能的,但只是想确认一下。
我正在编写一个简单的WPF应用程序,并希望我的样式在外部定义,因此您基本上可以将样式作为外部资源加载。有点像CSS和HTML通常是分开的......
然而,有一件事让我感到困惑,那就是HTML& CSS更像是一种外在的方法,CSS以元素为目标并应用于匹配元素。但是对于WPF来说,它似乎是相反的,你必须告诉元素应该应用哪些样式,但这似乎不是动态。所以我只想知道是否有一种方法可以应用样式,因此样式只是针对元素。
一个例子是:
<Style TargetType="{x:Type TextBox}" TargetElement="{x:Name SomeTextboxElement}">
<Setter Property="Width" Value="Auto"/>
</Style>
通常你必须用样式指定一个键,然后获取要映射到样式键的元素(SomeTextboxElement)。
显然给每个元素一个样式绑定似乎有点傻了,它应该更加层次化并过滤掉(这可能是,我只是不知道如何)而不是一对一的映射。永远需要为整个应用程序设计风格...
希望有道理......
答案 0 :(得分:2)
你所说的你正在寻找的是有趣的,但不适用于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>
现在有些假设。如果满足两个条件,你想要的东西将非常容易实现:
鉴于此并将其与触发器/多重触发器组合,然后可以为ParentVisual.VisualType创建触发器。
让我们为WPF定义一些假设的CSS,将样式应用于包含在网格中的Id“subnavi”的Border中包含的任何TextBox。
Grid Border#subnavi TextBox
{
backgroundColor:#FF0000;
}
转换为WPF,这将是具有三个条件的TextBox的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更可取。答案 1 :(得分:1)
我不知道你是否还想这样做,但是Colin Eberhardt在此前做了一些事情:http://www.codeproject.com/Articles/36499/Using-CSS-Selectors-for-Styling-in-WPF
答案 2 :(得分:0)
您正在寻找隐式风格。它们不像css选择器那样精细,但您可以为每种类型的元素定义样式。例如,以下示例说:“我希望所有按钮的宽度都为80”
<Style TargetType="{x:Type Button}">
<Setter Property="Width" Value="80"/>
</Style>
这些定义可以在几个不同的范围内完成:应用程序,页面,控件或任何框架元素,只需将其添加为资源即可。搜索隐式样式时,运行时将采用自下而上的方法,它将使用它创建的第一个。
请查看this article了解更多详情。