应用自定义样式时覆盖WPF模板

时间:2013-08-01 09:23:10

标签: wpf xaml styles controltemplate

我在app.xaml中为组合框定义了一个全局样式,如下所示:

<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
    <Setter Property="MinHeight" Value="20"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBox">
                <Grid Width="{TemplateBinding Width}">
                    <ToggleButton 
                                        Name="ToggleButton" 
                                        Template="{StaticResource ComboBoxToggleButton}" 
                                        Grid.Column="2" 
                                        Focusable="false"
                                        IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                                        ClickMode="Press">
                    </ToggleButton>
                    <ContentPresenter
                                        Name="ContentSite"
                                        IsHitTestVisible="False" 
                                        Content="{TemplateBinding SelectionBoxItem}"
                                        ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
                                        ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
                                        Margin="3,3,23,3"
                                        VerticalAlignment="Center"
                                        HorizontalAlignment="Left" />
                    <TextBox x:Name="PART_EditableTextBox"
                                        Style="{x:Null}" 
                                        Template="{StaticResource ComboBoxTextBox}" 
                                        HorizontalAlignment="Left" 
                                        VerticalAlignment="Center" 
                                        Margin="3,3,23,3"
                                        Focusable="True" 
                                        Background="Transparent"
                                        Visibility="Hidden"
                                        IsReadOnly="{TemplateBinding IsReadOnly}"/>
                    <Popup 
                                        Name="Popup"
                                        Placement="Bottom"
                                        IsOpen="{TemplateBinding IsDropDownOpen}"
                                        AllowsTransparency="True" 
                                        Focusable="False"
                                        PopupAnimation="Slide">
                        <Grid 
                                            Name="DropDown"
                                            SnapsToDevicePixels="True"                
                                            MinWidth="{TemplateBinding ActualWidth}"
                                            MaxHeight="{TemplateBinding MaxDropDownHeight}">
                            <Border x:Name="DropDownBorder" Background="{StaticResource BackgroundBrush}" />
                            <ScrollViewer Margin="4,4,4,4" SnapsToDevicePixels="True" Style="{StaticResource DropDownScrollViewer}">
                                <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                            </ScrollViewer>
                        </Grid>
                    </Popup>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="HasItems" Value="false">
                        <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
                    </Trigger>
                    <Trigger Property="IsGrouping" Value="true">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                    </Trigger>
                    <Trigger Property="IsEditable" Value="true">
                        <Setter Property="IsTabStop" Value="false"/>
                        <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
                        <Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

然后我在控件中创建一个组合框:

<ComboBox Name="DataTypeSelector" ItemsSource="{Binding ElementName=DataItemsBuildWindow, Path=DataContext.Types}" SelectedValue="{Binding DataType}" HorizontalAlignment="Stretch" />                                      

样式按预期应用。

如果我将控件中的组合框更改为下面的组合框,组合框将恢复其原始样式和宽度并触发定义的工作。似乎忽略了新的全球风格。

<ComboBox Name="DataTypeSelector" ItemsSource="{Binding ElementName=DataItemsBuildWindow, Path=DataContext.Types}" SelectedValue="{Binding DataType}" HorizontalAlignment="Stretch">
                                    <ComboBox.Style>
                                        <Style TargetType="ComboBox">
                                            <Setter Property="Width" Value="160"></Setter>
                                            <Style.Triggers>
                                                <DataTrigger Value="List" Binding="{Binding SelectedValue, ElementName=DataTypeSelector, Converter={StaticResource ToStringConverter}}">
                                                    <Setter Property="Width" Value="80" />
                                                </DataTrigger>
                                            </Style.Triggers>
                                        </Style>
                                    </ComboBox.Style>
                                </ComboBox>

如何保留全局样式,还应用自定义触发器?

1 个答案:

答案 0 :(得分:13)

您必须将新样式基于现有的默认样式:

<ComboBox.Style>
    <Style TargetType="ComboBox"
           BasedOn="{StaticResource ResourceKey={x:Type ComboBox}}">
        ...
    </Style>
</ComboBox.Style>

顺便说一下,没有必要在App.xaml的资源字典中设置默认样式的键。如果指定TargetType="ComboBox",则默认情况下将密钥设置为该类型。所以这就足够了:

<Style TargetType="ComboBox">
    ...
</Style>