假设我有一个共同的UserControl
,它的默认值为ControlTemplate
。现在我想添加一个AdornerDecorator
作为ControlTemplate
。
我该怎么做?
到目前为止,我的尝试如下:
UserControl view;
var templateWithAdornerDecorator = new ControlTemplate(view.GetType());
var adornerDecorator = new FrameworkElementFactory(typeof(AdornerDecorator));
var otherView = new FrameworkElementFactory(view.GetType());
otherView.SetValue(Control.TemplateProperty, view.Template);
adornerDecorator.AppendChild(otherView);
templateWithAdornerDecorator.VisualTree = adornerDecorator;
view.Template = templateWithAdornerDecorator;
(我的view
可能是UserControl
的派生类型。)
但是这会导致StackOverflowException崩溃:(
修改
MyUserControl
有这个xaml:
<UserControl x:Class="MyNameSpace.Wpf.Sample.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
ABA
</UserControl>
这是xaml.cs:
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
}
}
答案 0 :(得分:1)
您需要创建模板的副本。您可以使用XamlWriter
/ XamlReader
类克隆现有模板。
试试这个:
MyUserControl view = new MyUserControl();
string xaml;
ControlTemplate ct = view.Template;
using (var stream = new System.IO.MemoryStream())
{
System.Windows.Markup.XamlWriter.Save(ct, stream);
xaml = Encoding.ASCII.GetString(stream.ToArray());
}
XNamespace ns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
XDocument oldTemplateXml = XDocument.Parse(xaml);
XElement newTemplateXml = new XElement(ns + "ControlTemplate",
new XElement(ns + "AdornerDecorator", oldTemplateXml.Root.DescendantNodes().First()));
ControlTemplate newTemplate = System.Windows.Markup.XamlReader.Parse(newTemplateXml.ToString()) as ControlTemplate;
view.Template = newTemplate;