在WPF中继承样式

时间:2013-09-04 15:47:16

标签: c# wpf mvvm styles datatemplate

我的MainWindow.xaml中有以下代码,它遵循Josh Smith的MVVM工作区模型。

<Grid Grid.Row="1" 
      Grid.RowSpan="2">
    <ContentControl
        Content="{Binding}" 
        ContentTemplate="{StaticResource WorkspaceTemplate}">
    </ContentControl>
</Grid>

最初我的工作区模板是

<DataTemplate x:Key="WorkspaceTemplate">
    <TabControl x:Name="tabControl" 
                IsSynchronizedWithCurrentItem="true" 
                ItemsSource="{Binding Workspaces}" 
                SelectedIndex="{Binding SelectedIndex}"
                HorizontalContentAlignment="Stretch" 
                VerticalContentAlignment="Stretch" 
                HorizontalAlignment="Stretch" 
                VerticalAlignment="Stretch" 
                TabStripPlacement="Top" 
                Margin="5,0,5,0">
        <TabControl.ItemContainerStyle>
            <Style TargetType="TabItem">
                <Setter Property="Header" Value="{Binding Path=DisplayName}"/>
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                <Setter Property="VerticalContentAlignment" Value="Stretch"/>
            </Style>
        </TabControl.ItemContainerStyle>
    </TabControl>
</DataTemplate>

现在我创建了一个带有关闭按钮的TabControl样式,该样式包含在单独的资源字典中。这个代码类似于

<Style x:Key="StudioTabControl" TargetType="{x:Type TabControl}">
    <Style.Resources>
        <Style x:Key="StudioTabItem" TargetType="{x:Type TabItem}">
            <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Grid Height="20" 
                              Background="{TemplateBinding Background}" 
                              SnapsToDevicePixels="True">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="35"/>
                            </Grid.ColumnDefinitions>
                            <ContentPresenter Grid.Column="0" 
                                              Margin="10,0,10,0" 
                                              HorizontalAlignment="Center" 
                                              VerticalAlignment="Center" 
                                              ContentSource="Header" />
                            <Button Grid.Column="1" 
                                    Width="15" 
                                    Height="15" 
                                    HorizontalAlignment="Center" 
                                    VerticalAlignment="Center" 
                                    DockPanel.Dock="Right">
                            ... ect.

问题是如何将此StudioTabControl样式继承到我的<DataTemplate x:Key="WorkspaceTemplate">定义中。目前我已经尝试了

<DataTemplate x:Key="WorkspaceTemplate">
    <TabControl x:Name="tabControl" 
                ItemsSource="{Binding Workspaces}" 
                SelectedIndex="{Binding SelectedIndex}"
                Style="{StaticResource StudioTabControl}"
                ... ect.

但由于我在<TabControl.ItemContainerStyle>...定义中指定了<DataTemplate x:Key="WorkspaceTemplate">,因此样式不起作用。 如何让我的StudioTabItem样式与现有WorkspaceTemplate一起使用?

感谢您的时间。

3 个答案:

答案 0 :(得分:3)

我没有看到它是如何继承样式的,如果你想在“WorkspaceTemplate”中使用“StudioTabControl”样式,只需使用它:

<TabControl x:Name="tabControl" 
                IsSynchronizedWithCurrentItem="true" 
                ItemsSource="{Binding Workspaces}" 
                SelectedIndex="{Binding SelectedIndex}"
                HorizontalContentAlignment="Stretch" 
                VerticalContentAlignment="Stretch" 
                HorizontalAlignment="Stretch" 
                VerticalAlignment="Stretch" 
                TabStripPlacement="Top" 
                Style="{StaticResource StudioTabControl}"
                Margin="5,0,5,0">

它正在寻找的TabControl样式不是TabItem样式,因为StudioTabItem的TargetType是TabItem而不是TabControl,因此它不会被应用。

或者,如果您真的在寻找Style Inheritence,请查看此link

答案 1 :(得分:1)

使用BasedOn继承样式:

 <Style TargetType="TabItem" BasedOn="{StaticResource StudioTabItem}">
            <Setter Property="Header" Value="{Binding Path=DisplayName}"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="VerticalContentAlignment" Value="Stretch"/>
  </Style>

您需要定义StudioTabItem以便“TabItem”样式定义可以访问它,因此在定义TabItem之前定义它:

 <Style x:Key="StudioTabItem" TargetType="{x:Type TabItem}"> 

答案 2 :(得分:1)

任何元素的资源中定义的资源只能在该元素中使用,因此您在TabControl.Style中定义的样式将无法在其外部使用,因此不会应用。

因此,为了使用该样式,请将其从Tabcontrol.Style中取出,即与资源字典中的tabcontrol样式并行定义。

其次,如果您使用键定义了Style,则不会自动应用。您必须使用{StaticResource=Key}.

明确应用它

在tabcontrol.Style之外定义它之后,您可以使用ItemContainerStyle中的BasedOn关键字继承它,如

<Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource StudioTabItem}">

感谢