<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下this
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的就缺失了部分,也包括事件處理這些,由於序列化是被限制爲邏輯樹中自包含,沒有能夠保存事件處理的設施code
咱們能夠經過contentcontrol來存資源component
<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>
這個就能夠屢次建立模板了orm
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; }