Copy a Xaml object
<Control.Resources>
<Button Click="Button_OnClick" x:Key="MyButton">
<Border Margin="10" CornerRadius="4" Background="White" Width="200" Height="200">
<Grid>
<StackPanel VerticalAlignment="Top">
<Border Height="100" Margin="0,10,0,0">
<Border.Background>
<ImageBrush ImageSource="/DefenseTest;component/Resources/123.png" Stretch="Uniform"/>
</Border.Background>
</Border>
<TextBlock Name="MyText" HorizontalAlignment="Center" Text="test"></TextBlock>
</StackPanel>
</Grid>
</Border>
</Button>
</Control.Resources>
然后
Button button =(Button)Resources["MyButton"];
Button button2=button.XamlClone();
你并不能直接多次(Button)Resources["MyButton"];会是同一个引用
所以需要clone下
public static class ExtensionMethods
{
public static T XamlClone<T>(this T original)
where T : class
{
if (original == null)
return null;
object clone;
using (var stream = new MemoryStream())
{
XamlWriter.Save(original, stream);
stream.Seek(0, SeekOrigin.Begin);
clone = XamlReader.Load(stream);
}
if (clone is T)
return (T)clone;
else
return null;
}
}
https://msdn.microsoft.com/en-us/library/ms754193.aspx
但是这种方法有弊端,只能用来保存点文本和图形数据
里面的eventhandler,资源uri,,binding都会没,有的资源会形成一个自己的component,不再是引用的资源了
另外copy的对象不是一开是xaml里写好的,因为中途可能改动了,或者被优化了,然后save的就缺失了部分,也包括事件处理这些,因为序列化是被限制为逻辑树中自包含,没有可以保存事件处理的设施
我们可以通过contentcontrol来存资源
<Control.Resources>
<DataTemplate x:Key="MyButton">
<Button Click="Button_OnClick">
<Border Margin="10" CornerRadius="4" Background="White" Width="200" Height="200">
<Grid>
<StackPanel VerticalAlignment="Top">
<Border Height="100" Margin="0,10,0,0">
<Border.Background>
<ImageBrush ImageSource="/DefenseTest;component/Resources/123.png" Stretch="Uniform"/>
</Border.Background>
</Border>
<TextBlock Name="MyText" HorizontalAlignment="Center" Text="test"></TextBlock>
</StackPanel>
</Grid>
</Border>
</Button>
</DataTemplate>
</Control.Resources>
这个就可以多次创建模板了
ContentControl content=new ContentControl();
content.ContentTemplate = (DataTemplate)FindResource("MyButton");
content.Loaded += (s, e) =>
{
var textBlock = MyVisualTreeHelper.FindVisualChildItem<TextBlock>((ContentControl) content, "MyText");
textBlock.Text = "test";
};
public static ChildItem FindVisualChildItem<ChildItem>(DependencyObject obj, string name) where ChildItem : FrameworkElement
{
if (null != obj)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is ChildItem && (child as ChildItem).Name.Equals(name))
{
return (ChildItem)child;
}
else
{
ChildItem childOfChild = FindVisualChildItem<ChildItem>(child, name);
if (childOfChild != null && childOfChild is ChildItem && (childOfChild as ChildItem).Name.Equals(name))
{
return childOfChild;
}
}
}
}
return null;
}