用最少的代码重现替换ControlTemplate

时间:2015-04-28 12:44:35

标签: wpf combobox styling controltemplate

我想修改标准WPF ComboBox,以便在IsEditable设置为true时在左侧显示图片。

这就是我最终的结果:

包含以下内容的单独XAML文件中的ResourceDictionary

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
    <LinearGradientBrush x:Key="ButtonNormalBackground" StartPoint="0,0" EndPoint="0,1">...</LinearGradientBrush>
    <SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
    <LinearGradientBrush x:Key="TextBoxBorder">...</LinearGradientBrush>
    <Style x:Key="ComboBoxFocusVisual">...</Style>
    <Style x:Key="ComboBoxEditableTextBox" TargetType="{x:Type TextBox}">...</Style>
    <Geometry x:Key="DownArrowGeometry">M 0 0 L 3.5 4 L 7 0 Z</Geometry>
    <Style x:Key="ComboBoxReadonlyToggleButton" TargetType="{x:Type ToggleButton}">...</Style>
    <Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">...</Style>
    <ControlTemplate x:Key="ComboBoxEditableTemplate" TargetType="{x:Type ComboBox}">...</ControlTemplate>
    <Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">...</Style>
</ResourceDictionary>

以及Resources属性中的include指令,无论我想在哪里应用新模板:

<StackPanel.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="EditableComboBoxWithImage.xaml" />
        </ResourceDictionary.MergedDictionaries>
        ....
    </ResourceDictionary>
<StackPanel.Resources>

我只修改了<ControlTemplate x:Key="ComboBoxEditableTemplate" TargetType="{x:Type ComboBox}">...</ControlTemplate>

中的一个小东西

我知道我不能只替换ControlTemplate的一部分,因此<ControlTemplate x:Key="ComboBoxEditableTemplate" TargetType="{x:Type ComboBox}">...</ControlTemplate>必须完全复制。

现在我的问题是:是否有可能以某种方式通过链接到它们来摆脱ResourceDictionary的其他内容,因为它们是标准WPF的一部分?

1 个答案:

答案 0 :(得分:0)

如果您询问是否可以从XAML中的默认ComboBox ControlTemplate引用原始内部控件,那么很遗憾答案是否,您不能 ...想一想是一个班级的private成员。

如果您不介意使用代码,那么您可以使用ControlTemplate类的FindName method来提取它们,但实际上,它的工作量超出了它的价值:

TextBox editableTextBox = (TextBox)controlWithDefaultControlTemplateApplied.Template.
    FindName("PART_EditableTextBox", controlWithDefaultControlTemplateApplied);