【问题标题】:Can I have one Style with multiple TargetType in WPF?我可以在 WPF 中拥有一个具有多个 TargetType 的样式吗?
【发布时间】:2012-03-03 05:44:23
【问题描述】:

如标题,我的意思如下:

<Style TargetType="{x:Type TextBlock}" 
       TargetType="{x:Type Label}"  
       TargetType="{x:Type Button}" >

这其实是为了使用第三方控件,我继承了他们的类。但是模板不适用于子类,因为TargetType 在基类上。所以我想设置多个TargetTypes,让它可以同时申请。

【问题讨论】:

标签: c# wpf silverlight targettype


【解决方案1】:

不,你不能,但是我经常为共享基类创建一个样式,例如FrameworkElement,然后创建我的个人控件样式BasedOn 基样式

<Style TargetType="{x:Type FrameworkElement}">
    <!-- Shared Setters -->
</Style>

<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />

【讨论】:

  • 很遗憾,FrameworkElement 没有包含许多属性(例如与字体相关的属性),因此无法将它们包含在样式设置器中。您可以选择 ContentControl 代替,但这不适用于此特定示例,因为 TextBlock 不继承自 ContentControl.
【解决方案2】:

Rachel 答案的一个更灵活的变体是使用 resourceKey 作为 BasedOn。

所以,而不是:

<Style TargetType="{x:Type FrameworkElement}">
    <!-- Shared Setters -->
</Style>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />


执行以下操作:

<Style x:Key="commonStyle" TargetType="{x:Type FrameworkElement}">
    <!-- Shared Setters -->
</Style>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource commonStyle}" />


这提供了更多选项,因为某些样式可以基于 commonStyle,而某些样式可以基于例如commonStyle2,commonStyle 和 commonStyle2 都将 FrameworkElement 作为目标类型。

【讨论】:

    【解决方案3】:

    答案是否定的。

    TargetType 是 Style 的一个属性,只能设置一次。为确保类型安全,样式应针对特定类型,以便知道要设置哪些属性。

    但是,有一个解决方法。您可以采用所有类型的通用属性并以一种样式定义它们。然后为每个特定控件制作特定样式,并使用BasedOn 属性继承基本样式。

    【讨论】:

      【解决方案4】:

      根据 Rachel 的回答,为了更简洁的代码,您可以删除标记扩展中的 x:Type 并仅使用 Type:

      <Style TargetType="Label">
          <!-- Shared Setters -->
      </Style>
      

      等同于:

      <Style TargetType="{x:Type Label}">
          <!-- Shared Setters -->
      </Style>
      

      【讨论】:

        【解决方案5】:

        实际上我发现在一个网格中你只能设置一个项目的样式。但是,在堆栈面板中,您可以设置多个项目的样式。

        查看此代码:

        <Grid>        
            <StackPanel>
                <StackPanel.Resources>
                    <Style TargetType="TextBlock">
                        <Setter Property="FontSize" Value="12"></Setter>
                        <Setter Property="VerticalAlignment" Value="Center"></Setter>
                        <Setter Property="HorizontalAlignment" Value="Center"></Setter>
                        <Setter Property="Margin" Value="5"></Setter>
                    </Style>
                    <Style TargetType="TextBox">
                        <Setter Property="Width" Value="100"></Setter>
                        <Setter Property="Height" Value="25"></Setter>
                        <Setter Property="Margin" Value="5"></Setter>
                    </Style>
                    <Style TargetType="Button">
                        <Setter Property="Margin" Value="5"></Setter>
                        <Setter Property="Height" Value="30"></Setter>
                        <Setter Property="Width" Value="100"></Setter>
                    </Style>
                </StackPanel.Resources>
                <StackPanel Orientation="Horizontal">
                    <TextBlock>Kanban ID</TextBlock>
                    <TextBox></TextBox>
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock>Customer Name</TextBlock>
                    <TextBox></TextBox>
                </StackPanel>            
                <Button>Save</Button>
            </StackPanel>
        </Grid>
        

        如果您要删除它下方的位置并更改为,您将看到对象未设置,仅更改了最后一个对象的属性。

        希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 2021-05-06
          • 2011-01-27
          • 1970-01-01
          • 1970-01-01
          • 2022-08-21
          • 2020-12-19
          • 2017-06-24
          • 2018-11-05
          • 2018-04-04
          相关资源
          最近更新 更多