用最少的代码复制替换 ControlTemplate

Replace ControlTemplate with minimum code reproduction

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

这就是我最终得到的结果:

A ResourceDictionary 在单独的 XAML 文件中,包含以下内容:

<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 的一部分?

如果您问是否可以从 XAML 中的默认 ComboBox ControlTemplate 引用原始内部控件,那么很遗憾,答案是 不,您不能...想想他们是 class.

private 成员

如果您不介意使用代码,那么您可以使用 ControlTemplate class 的 FindName method 来提取它们,但实际上,这样做得不偿失:

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