【问题标题】:How to set Control Template in code?如何在代码中设置控件模板?
【发布时间】:2018-10-25 15:55:06
【问题描述】:

我在 XAML 中有这个

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

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

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

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

【问题讨论】:

    标签: c# wpf xaml contentcontrol


    【解决方案1】:

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

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

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

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

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

    设置 ControlTemplate 以编程方式就像使用 XAML 因为我们必须使用 XamlReader 类。

    那句话是错误的,我们没有“必须”


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


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

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

    我想知道这个建议是否是个好主意。如果我可以避免使用字符串和XamlReader,我个人仍然会在 XAML 中将模板定义为资源。

    【讨论】:

    • 谢谢完美...我知道这不是一个好主意,但在一个特定情况下我别无选择
    • 好吧,我只是引用了我找到的网站的文字。。使用XamlReader.Parse有什么问题?
    • @Ai_boy:这只是 XAML 的解析,这是不必要的,我不建议这样做,如果您有静态 XAML,最好将其创建为 XAML 资源,而不是将 XML 字符串破解为代码隐藏。
    • @h-b 哦,我明白了.. 我认为“动态”Xaml 不适合商业应用程序,所以.. 这两种方法对我来说就像“肮脏的黑客”.. 无论如何 tnx 适合你回答。
    【解决方案2】:

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

    设置 ControlTemplate 以编程方式就像使用 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 因为 ControlTemplate、Border、 和我们需要的其他控件被定义 那里。如果我们不包括它,我们将 遇到运行时异常。 基本上,我们必须把 模板所需的命名空间。

    【讨论】:

      【解决方案3】:

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

      1. 创建一个依赖属性,该属性将代表您何时想要 更改图像(布尔值)或者您可以创建一个具有 所有可能的图片都说
      2. 枚举图像 { Image1 = 0, Image2 = 1, Image2 = 3}。创建此类型的依赖属性“CurrentButtonImage”,它将与按钮关联。

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

      在 CurrentButtonImage 的属性更改上使用

      更新按钮的图像(在后面的代码中)
      CurrentImagePropertyChangedhandler(....,...)  
      {  
          switch(CurrentButtonImage)  
          {  
              case "Image1" :  
                this._ButtonImage.Fill = (DrawingBrush)csd.FindResource("Image1DrawingBrush");
                break;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-07
        • 2013-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多