我在XAML中有以下内容
<ControlTemplate TargetType="{x:Type Button}">
<Image ...>
</ControlTemplate>
我希望在 C# 代码中实现同样的功能。我该如何实现?
ControlTemplate ct = new ControlTemplate();..
Image img = new Image();..
现在该如何将此图像分配给控件模板?我们可以这样做吗,还是我漏掉了什么概念?我在XAML中有以下内容
<ControlTemplate TargetType="{x:Type Button}">
<Image ...>
</ControlTemplate>
我希望在 C# 代码中实现同样的功能。我该如何实现?
ControlTemplate ct = new ControlTemplate();..
Image img = new Image();..
现在该如何将此图像分配给控件模板?我们可以这样做吗,还是我漏掉了什么概念?在代码后端创建模板不是一个好主意,理论上,应该通过定义 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 方法来以编程方式创建模板。
我想知道这个建议是否好。如果可以避免使用字符串和 XamlReader
,我个人仍然会选择在XAML中将模板定义为资源。
通过编程设置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中在按钮模板中使用它
在CurrentButtonImage的属性更改时,使用代码更新按钮的图像(在代码后台中)
CurrentImagePropertyChangedhandler(....,...)
{
switch(CurrentButtonImage)
{
case "Image1" :
this._ButtonImage.Fill = (DrawingBrush)csd.FindResource("Image1DrawingBrush");
break;
}
}
XamlReader.Parse
有什么问题吗? - obenjiro