应用自定义样式时覆盖 WPF 模板
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17990043/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF template overridden when custom style applied
提问by VARAK
I have a global style defined for a combobox in app.xaml as below:
我在 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>
Then I create a combobox in a control:
然后我在控件中创建一个组合框:
<ComboBox Name="DataTypeSelector" ItemsSource="{Binding ElementName=DataItemsBuildWindow, Path=DataContext.Types}" SelectedValue="{Binding DataType}" HorizontalAlignment="Stretch" />
The style is applied as expected.
样式按预期应用。
If I change my combobox in the control to the below, the combobox goes back to its original style and the width and triggers defined work. It seems that the new global style is ignored.
如果我将控件中的组合框更改为下面的组合框,组合框将返回其原始样式和宽度并触发定义的工作。似乎忽略了新的全局样式。
<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>
How can I keep the global style but also apply the custom triggers?
如何在保持全局样式的同时应用自定义触发器?
回答by Clemens
You have to base the new style on the existing default style:
您必须基于现有的默认样式创建新样式:
<ComboBox.Style>
<Style TargetType="ComboBox"
BasedOn="{StaticResource ResourceKey={x:Type ComboBox}}">
...
</Style>
</ComboBox.Style>
By the way, it is not necessary to set the key of the default style in the resource dictionary in App.xaml. If you specify TargetType="ComboBox"the key is set to that type by default. So this is sufficient:
顺便说一下,App.xaml 中的资源字典中默认样式的key 不需要设置。如果指定TargetType="ComboBox"键默认设置为该类型。所以这就足够了:
<Style TargetType="ComboBox">
...
</Style>

