我在XAML中有这个
<ControlTemplate TargetType="{x:Type Button}">
<Image ...>
</ControlTemplate>
我希望在C#代码中实现相同的功能。我怎样才能做到这一点?
ControlTemplate ct = new ControlTemplate();..
Image img = new Image();..
现在如何将此图像分配给控制模板?我们可以这样做还是我错过了这里的任何概念?
答案 0 :(得分:29)
在代码隐藏中创建模板不是一个好主意,理论上可以通过定义ControlTemplate.VisualTree
FrameworkElementFactory
来实现。
ControlTemplate template = new ControlTemplate(typeof(Button));
var image = new FrameworkElementFactory(typeof(Image));
template.VisualTree = image;
分配属性非常迂回,因为您需要使用SetValue
和SetBinding
:
image.SetValue(Image.SourceProperty, ...);
此外,关于(先前)接受的答案和引用的内容:
设置ControlTemplate 以编程方式就像使用一样 XAML因为我们必须使用 XamlReader类。
该陈述是错误的,我们不“必须”。
如果我在运行时分配模板,我将它们定义为可以在需要时加载的资源。
修改:根据文档FrameworkElementFactory
已弃用:
这个类是一种不常用的方式,以编程方式创建模板,模板是FrameworkTemplate的子类,如ControlTemplate或DataTemplate;使用此类创建模板时,并非所有模板功能都可用。以编程方式创建模板的推荐方法是使用XamlReader类的Load方法从字符串或内存流加载XAML。
我想知道这个建议是不是一个好主意。我个人仍然会将模板定义为XAML中的资源,如果我可以避免使用字符串和XamlReader
。
答案 1 :(得分:23)
设置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, 和我们需要的其他控制被定义 那里。如果我们不包括它,我们会 遇到运行时异常。 基本上,我们必须把 模板所需的名称空间。
答案 2 :(得分:0)
如果您只需要更改按钮图像,那么您可以做一件事。
现在在XAML中,在按钮模板中使用它
On属性更改CurrentButtonImage使用
更新按钮的图像(在代码后面)CurrentImagePropertyChangedhandler(....,...)
{
switch(CurrentButtonImage)
{
case "Image1" :
this._ButtonImage.Fill = (DrawingBrush)csd.FindResource("Image1DrawingBrush");
break;
}
}