如何扩展从UserControl中的父容器继承的样式
本文关键字:样式 继承 UserControl 何扩展 扩展 | 更新日期: 2023-09-27 18:15:37
我有一个StackPanel
里面有一个UserControl
:
<StackPanel>
<local:MyUC/>
</StackPanel>
UserControl
包含各种TextBoxes
和其他控件,通过ResourceDictionary
设置它们的样式,以实现整个应用程序的通用外观。对于TextBox
, ResourceDictionary
条目看起来像这样:
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="MaxWidth" Value="{Binding RelativeSource={RelativeSource AncestorType=Border},Path=ActualWidth}"/>
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
</Style>
现在我想将父控件(StackPanel
)中的默认样式应用于UserControl
中的所有TextBox
es,因此我可以将TextBox
es的IsReadOnly
-属性绑定到仅在父模型中可用的属性:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Style.Triggers>
<DataTrigger Binding="{Binding Model.State}" Value="ReadOnly">
<Setter Property="IsReadOnly" Value="True"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<local:MyUC/>
</StackPanel>
不幸的是,在UserControl
的ResourceDictionary
中定义的TargetType="{x:Type TextBox}"
的默认样式覆盖了我试图在父StackPanel
中设置的样式。
我如何实现扩展的默认样式,是在StackPanel.Resources
内定义的默认样式在UserControl
和ResourceDictionary
中定义的,而不是覆盖它?
这就是我所做的,我从来没有遇到过问题:
在ResourceDictionary:<Style x:Key="TextBoxBase" TargetType="{x:Type TextBox}">
<!-- Default styles go here -->
</Style>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource TextBoxBase}"/>
这确保了除非另有规定,所有的文本框都将具有TextBoxBase
样式,而不是更多或更少。
当定义必须具有上述属性的样式时,您可以这样定义样式(在您的情况下,此样式是StackPanel的一部分):
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource TextBoxBase}">
<Style.Triggers>
<!-- These triggers should be in ADDITION to triggers defined in TextBoxBase.-->
<DataTrigger Binding="{Binding Model.State}" Value="ReadOnly">
<Setter Property="IsReadOnly" Value="True"/>
</DataTrigger>
</Style.Triggers>
</Style>
另一个问题可能是您为控件中包含的TextBoxes定义了样式。如果你的目标样式的文本框是唯一的控件,他们被包含在,为什么不在控件本身定义它们?要做到这一点,只需在控件上绑定一个对ViewModel的引用,然后在控件中使用该引用,使用上述方法将DataTrigger应用于每个TextBox。