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下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;
}
相關文章
相關標籤/搜索