【问题标题】:How to extend a style inherited from a parent container in an UserControl?如何扩展从 UserControl 中的父容器继承的样式?
【发布时间】:2023-03-31 08:11:01
【问题描述】:

我有一个StackPanel,里面有一个UserControl

<StackPanel>
    <local:MyUC/>
</StackPanel>

UserControl 包含各种TextBoxes 和其他通过ResourceDictionary 设置样式的控件,以实现整个应用程序的共同外观。
对于TextBoxes,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 内的所有TextBoxes,这样我就可以绑定IsReadOnly-属性@987654334 @es 到仅在父模型中可用的属性:

<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>

不幸的是,在UserControlResourceDictionary 内部定义的TargetType="{x:Type TextBox}" 的默认样式覆盖了我尝试在父StackPanel 中设置的样式。

我怎样才能扩展 StackPanel.Resources 中定义的默认样式,而不是覆盖它?

【问题讨论】:

    标签: c# wpf xaml user-controls


    【解决方案1】:

    这就是我所做的,我从来没有遇到过问题:

    在资源字典中:

    <Style x:Key="TextBoxBase" TargetType="{x:Type TextBox}">
        <!-- Default styles go here -->
    </Style>
    <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource TextBoxBase}"/>
    

    这确保除非另有说明,否则所有 TextBox 都将具有 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 定义样式。如果您定位样式的 TextBox 与它们所包含的控件是唯一的,为什么不在控件本身中定义它们呢?为此,您只需在控件上绑定对 ViewModel 的引用,然后在控件中使用该引用通过上述方法将 DataTrigger 应用到每个 TextBox。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-06
      • 2011-06-25
      • 2014-11-06
      • 2017-10-19
      • 1970-01-01
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多