如何在代码中设置控件模板

本文关键字:控件 设置 代码 | 更新日期: 2023-09-27 17:52:40

我在 XAML 中有这个

<ControlTemplate TargetType="{x:Type Button}">
    <Image ...>
</ControlTemplate>

我想在 C# 代码中实现相同的目标。我怎样才能做到这一点?

ControlTemplate ct = new ControlTemplate();..
Image img = new Image();..

现在如何将此图像分配给控件模板?我们可以这样做还是我在这里错过了任何概念?

如何在代码中设置控件模板

在代码隐藏中创建模板不是一个好主意,理论上可以通过定义FrameworkElementFactory ControlTemplate.VisualTree来做到这一点。

ControlTemplate template = new ControlTemplate(typeof(Button));
var image = new FrameworkElementFactory(typeof(Image));
template.VisualTree = image;

分配属性是非常迂回的,因为您需要使用 SetValueSetBinding

image.SetValue(Image.SourceProperty, ...);

另外,关于(以前(接受的答案和引用的内容:

设置控件模板 以编程方式就像使用 XAML,因为我们必须使用 XamlReader 类。

这种说法是错误的,我们"不必"。


如果我在运行时分配模板,我会将它们定义为可以在需要时加载的资源。


编辑:根据文档FrameworkElementFactory已弃用:

此类是以编程方式创建模板的已弃用方法,模板是 FrameworkTemplate 的子类,如 ControlTemplate 或 DataTemplate;使用此类创建模板时,并非所有模板功能都可用。以编程方式创建模板的建议方法是使用 XamlReader 类的 Load 方法从字符串或内存流加载 XAML。

我想知道这个建议是否是一个好主意。就个人而言,如果我能避免使用字符串和XamlReader,我仍然会选择将模板定义为 XAML 中的资源。

http://www.eggheadcafe.com/sample-code/SilverlightWPFandXAML/73fdb6a2-6044-4c43-8766-afa12618ddc1/set-controltemplate-programmatically.aspx

设置控件模板 以编程方式就像使用 XAML,因为我们必须使用 XamlReader 类。例如,这里是 设置按钮模板的代码, 假设我们要设置一个 按钮的模板,加载后。

private void Button_Loaded(object sender, RoutedEventArgs e) {
    var button = sender as Button;
    string template =
        "<ControlTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
            TargetType='"Button'">" +
            "<Border>" +
                 "<ContentPresenter/>" +
            "</Border>" +
        "</ControlTemplate>";
    button.Template = (ControlTemplate)XamlReader.Parse(template);
}

由于我们使用字符串来指定 模板的 XAML 代码,我们可以 使用 XamlReader 的 Parse 方法。这 XamlReader 还有一个 Load 方法, 主要用于流或 XAML 或 XML 读取器。请注意,我们 必须包含 XML 命名空间 http://schemas.microsoft.com/winfx/2006/xaml/presentation 因为控件模板、边框、 并定义了我们需要的其他控件 那里。如果我们没有包括它,我们将 遇到运行时异常。 基本上,我们必须将 模板所需的命名空间。

如果您只需要更改按钮图像,那么您可以做一件事。

  1. 创建一个依赖项属性,该属性将表示何时需要更改图像(布尔值(,或者您可以创建一个枚举,该枚举具有所有可能的图像都说
  2. 枚举图像 { 图像 1 = 0, 图像 2 =
  3. 1, 图像 2 = 3}。创建此类型的依赖项属性"当前按钮映像",该属性将与按钮关联。

现在在 XAML 中在按钮模板中使用它

属性上更改当前按钮图像更新按钮的图像(在代码隐藏中(

CurrentImagePropertyChangedhandler(....,...)  
{  
    switch(CurrentButtonImage)  
    {  
        case "Image1" :  
          this._ButtonImage.Fill = (DrawingBrush)csd.FindResource("Image1DrawingBrush");
          break;
    }
}