设置自定义控件的默认控件模板而不使用样式

时间:2019-10-17 13:14:52

标签: .net wpf custom-controls desktop-application

我正在寻找一种将自定义控件的默认Control Template牢固绑定到该控件的方法,而不是使用Style。我将在这里展示我最简单的示例来解释这一需求:

    public class UnitTextBox : TextBox
    {
        public string UnitLabel {...}
        public static readonly DependencyProperty UnitLabelProperty =
            DependencyProperty.Register("UnitLabel", typeof(string), typeof(UnitTextBox), new PropertyMetadata(""));
    }

此控件只是为单位标签(如毫米)添加了一个额外的字符串属性,给定以下从TextBox派生的简单控件模板,它将一个单位标签放在文本框中以保持环境的美观和整洁。尺寸正确:

    <ControlTemplate x:Key="UnitTextBoxTemplate" TargetType="{x:Type local:UnitTextBox}">
        <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
            <DockPanel>
                <TextBlock DockPanel.Dock="Right" Text="{TemplateBinding UnitLabel}" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="8,0,2,0" Focusable="False" IsHitTestVisible="False" Background="Transparent" Foreground="{TemplateBinding Foreground}"
                            FontSize="{TemplateBinding FontSize}" FontStyle="{TemplateBinding FontStyle}"   />
                <ScrollViewer x:Name="PART_ContentHost" Focusable="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
            </DockPanel>
        </Border>
...(triggers)
    </ControlTemplate>

所有这些都能很好地工作,但是此控件基本上仍然是TextBox,并且我已经使用了许多TextBox样式,因此我不想使用默认样式来应用模板:

    <Style  TargetType="{x:Type local:UnitTextBox}">
        <Setter Property="Template" Value="{DynamicResource UnitTextBoxTemplate}"/>
    </Style>

执行上述操作意味着我无法使用RegularTextBox风格的UnitTextBox风格。因此,每次我想添加UnitTextBox时,都必须明确指定使其正常运行的模板:

  <ctrl:UnitTextBox Template="{DynamicResource UnitTextBoxTemplate}" UnitLabel="mm/min" 
                    Style="{StaticResource RegularTextBox}"/>

我使用WPF已有很长时间了,但是我做的自定义控件相对较少,并且在使用它们时会使用默认样式方法,但是我认为必须会更好的方法,但是google-fu让我一次又一次失败。

我希望可以通过某种方法在UnitTextBox的构造函数/ Init例程中分配模板,但是我正努力从代码中访问资源字典;所以我想知道是否还有更深奥的方法。

1 个答案:

答案 0 :(得分:1)

如果您不想定义默认的Style,则可以在控件类中处理Loaded事件,并在事件处理程序中设置Template属性。

public UnitTextBox() : base()
{
    this.Loaded += UnitTextBox_Loaded;
}

private void UnitTextBox_Loaded(object sender, RoutedEventArgs e)
{
    var res = this.FindResource("UnitTextBoxTemplate");
    this.Template = res as ControlTemplate;
}