【问题标题】:Style doesn't inherit from another样式不会从另一个继承
【发布时间】:2016-04-08 09:05:22
【问题描述】:

我想创建一个 TabControl,其中所有 TabItem 具有相同的总体外观,但内部具有不同的图标。我所有的样式都在外部资源字典中。在主窗口中,我这样声明了我的控件:

<TabControl Grid.Row="2" TabStripPlacement="Left" >
        <TabItem Style="{StaticResource IconDev}">
            <Label Content="Content 1" />
        </TabItem>
        <TabItem Style="{StaticResource IconTab}">
            <Label Content="Content 2" />
        </TabItem>
    </TabControl

然后我创建了两种样式。首先是标签项的一般外观,然后是图标:

<Style x:Key="IconTab" TargetType="{x:Type TabItem}">
    <Setter Property="MinHeight" Value="70"/>
    <Setter Property="MaxHeight" Value="70"/>
    <Setter Property="MinWidth" Value="70"/>
    <Setter Property="MaxWidth" Value="70"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Grid>
                    <Border 
                        Name="Border"
                        Margin="0,0,-4,0" 
                        Background="#FFF"
                        BorderBrush="#FFF" 
                        BorderThickness="0" 
                        CornerRadius="0" >
                        <ContentPresenter x:Name="ContentSite"
                              VerticalAlignment="Center"
                              HorizontalAlignment="Center"
                              ContentSource="Header"
                              Margin="0"
                              RecognizesAccessKey="True"/>
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Panel.ZIndex" Value="100" />
                        <Setter TargetName="Border" Property="Background" Value="#000" />
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter TargetName="Border" Property="Background" Value="#000" />
                        <Setter TargetName="Border" Property="BorderBrush" Value="#000"/>
                        <Setter Property="Foreground" Value="#000"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Key="IconDev" TargetType="{x:Type TabItem}" BasedOn="{StaticResource IconTab}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <TabItem>
                    <TabItem.Header>
                        <StackPanel>
                            <Viewbox Width="50" Height="50">
                                <Frame Source="icon-dev.xaml" />
                            </Viewbox>
                        </StackPanel>
                    </TabItem.Header>
                </TabItem>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

但是有些东西不能很好地用于继承,因为Style="{StaticResource IconDev}" 只插入图标,但它不应用在Style="{StaticResource IconTab}" 中声明的一般布局。我做错了什么?

【问题讨论】:

  • IconDev 应该应用最小/最大尺寸设置(从基本样式继承)。它还重置(覆盖) TabItem 的模板。那怎么了?
  • 首先,它不应用来自IconTab 的触发器,它有一个默认的选项卡外观,里面有图标。其次,它似乎不起作用。单击时它不会切换选项卡。但它确实像你说的那样应用大小
  • IconDev tempate 擦除了用IconTab 编写的模板并且没有触发器。大小设置器独立于模板设置器,它们可以工作
  • 我完全是 wpf 的菜鸟,我可能在这里误解了继承的概念。那么有没有可能按照我的计划去做呢?

标签: .net wpf xaml


【解决方案1】:

IconDev 应该应用最小/最大尺寸设置(从基本样式继承)。它还重置(覆盖、擦除) TabItem 的模板。新模板没有触发器。大小设置器独立于模板设置器,它们可以工作

单个选项卡的选项卡标题内容可以从外部更改,而不是在模板中

例如两个 TabItem 都使用 IconTab 样式,第一个选项卡具有复杂的标题内容

<TabControl TabStripPlacement="Left" >
    <TabItem Style="{StaticResource IconTab}">
        <!--Label is a tab content-->
        <Label Content="Content 1" />

        <TabItem.Header>
            <StackPanel>
                <Viewbox Width="50" Height="50">
                    <Frame Source="icon-dev.xaml" />
                </Viewbox>
            </StackPanel>
        </TabItem.Header>
    </TabItem>

    <TabItem Style="{StaticResource IconTab}" Header="Text">
        <Label Content="Content 2" />
    </TabItem>
</TabControl>

更新:派生样式只能更改标题而不覆盖模板

<Style x:Key="IconDev" TargetType="{x:Type TabItem}" BasedOn="{StaticResource IconTab}">
    <Setter Property="Header">
        <Setter.Value>
                <StackPanel>
                    <Viewbox Width="50" Height="50">
                        <Frame Source="icon-dev.xaml" />
                    </Viewbox>
                </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
<TabControl  TabStripPlacement="Left" >
    <TabItem Style="{StaticResource IconDev}">
        <Label Content="Content 1" />                
    </TabItem>
    <TabItem Style="{StaticResource IconTab}" Header="Text">
        <Label Content="Content 2" />
    </TabItem>
</TabControl>

【讨论】:

  • 这就是我最初的做法,但我想让它更优雅,并在外部样式文件中做所有事情。谢谢
  • 你帮了我很大的忙,我终于开始了解这个机制是如何工作的
  • @przemoo83,谢谢。如果在某些时候您决定必须自定义帧源,这个问题 (stackoverflow.com/questions/9232502/…) 和链接的 Thomas Levesque 文章可能会有所帮助
猜你喜欢
  • 2019-09-15
  • 2015-09-19
  • 1970-01-01
  • 2018-01-24
  • 2017-04-03
  • 1970-01-01
  • 2014-12-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多