我怎样才能在运行时路径,已在XAML ResourceDictionary中被定义,多次添加到一个WPF形式? [英] How can I add a Path, that has been defined in the XAML ResourceDictionary, multiple times to a WPF form at runtime?

查看:199
本文介绍了我怎样才能在运行时路径,已在XAML ResourceDictionary中被定义,多次添加到一个WPF形式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在XAML定义的路径:

I have a defined path in XAML:

<UserControl.Resources>
    <ResourceDictionary>
        <Path x:Key="N44" Width="20" Height="80" Stretch="Fill" Fill="#FF000000" Data="M 20,25.2941L 20,29.4118L 15.9091,29.4118L 15.9091,40L 12.2727,40L 12.2727,29.4118L 2.54313e-006,29.4118L 2.54313e-006,25.6985L 13.4872,7.62939e-006L 15.9091,7.62939e-006L 15.9091,25.2941L 20,25.2941 Z M 12.2727,25.2941L 12.2727,5.28493L 2.09517,25.2941L 12.2727,25.2941 Z M 20,65.2941L 20,69.4118L 15.9091,69.4118L 15.9091,80L 12.2727,80L 12.2727,69.4118L -5.08626e-006,69.4118L -5.08626e-006,65.6985L 13.4872,40L 15.9091,40L 15.9091,65.2941L 20,65.2941 Z M 12.2727,65.2941L 12.2727,45.2849L 2.09517,65.2941L 12.2727,65.2941 Z "/>
    </ResourceDictionary>
</UserControl.Resources>



我想将它添加到WPF网格和放大器;做一次这样的作品:

I want to add it to a WPF Gird & doing it once like this works:

System.Windows.Shapes.Path aPath = new System.Windows.Shapes.Path();
aPath = (System.Windows.Shapes.Path)this.Resources["N44"];
LayoutRoot.Children.Add(aPath);



但是,如果我上添加一个按钮单击事件的代码,然后单击两次按钮,一个错误抛出声明

However if I add this code on a button click event and then click the button twice, an error is thrown stating

规定的目视已经是另一个Visual或
CompositionTarget根的子

"Specified Visual is already a child of another Visual or the root of a CompositionTarget."

然后我试图创建资源的两个实例,但我会继续接受同样的错误。下面是我用于此测试的代码:

I then attempted to create two instances of the resource but I have continued to receive the same error. Below is the code that I used for this test:

private void cmbTest_Click(object sender, System.Windows.RoutedEventArgs e)
  {
   System.Windows.Shapes.Path aPath = new System.Windows.Shapes.Path();
   aPath = (System.Windows.Shapes.Path)this.Resources["N44"];

   if (LayoutRoot.Children.Contains(aPath) == true){
    System.Windows.Shapes.Path bPath = (System.Windows.Shapes.Path)this.Resources["N44"];
    LayoutRoot.Children.Add(bPath); 
   }else{
    aPath.Name = "a";
    aPath.Tag = "a";
    LayoutRoot.Children.Add(aPath);
   }
  }



因此,我怎么可以添加一个XAML路径,这已在ResourceDictionary中多次在运行时被定义,一个WPF形式?

As such, how can I add an XAML Path, which has been defined in the ResourceDictionary, multiple times to a WPF form at runtime?

推荐答案

我自从发现我不得不错过了从MSDN 的文件的重要组成部分:

I've since found that I had missed an important part of the documentation from MSDN:

可共享类型和的UIElement类型:

Shareable Types and UIElement Types:

一个资源字典是一种技术
定义共享类型和
这些类型在XAML值。不是所有类型或$ B $的b值是适合于从
的ResourceDictionary用法。欲了解更多
了解哪些类型是
在Silverlight考虑共享,
见资源字典。

A resource dictionary is a technique for defining shareable types and values of these types in XAML. Not all types or values are suitable for usage from a ResourceDictionary. For more information on which types are considered shareable in Silverlight, see Resource Dictionaries.

特别是,所有的UIElement派生
型是不共享的,除非他们
来自模板和
A模板的应用程序在一个特定的控制
实例。不含模板的情况下,$ B $巴的UIElement预计只有在对象树存在
在一个地方一次
实例化,并且具有的UIElement
为可共享的将潜在违反
这一原则。

In particular, all UIElement derived types are not shareable unless they come from templates and application of a template on a specific control instance. Excluding the template case, a UIElement is expected to only exist in one place in an object tree once instantiated, and having a UIElement be shareable would potentially violate this principle.

我将归纳为,这不是它的作品,因为它不是创建一个新的实例我每次执行该代码 - 它只是创建对象的引用 - 这就是为什么它的工作一次,但不是多次。
所以多一点阅读后,我想出了3一项决议,我的问题的可能方式。

Which I will summarise as, that's not the way it works because it’s not creating a new instance each time I execute that code – it’s only creating a reference to the object – which is why it works once but not multiple times. So after a bit more reading I’ve come up with 3 potential ways for a resolution to my problem.

1)使用技术来创建一个深度复制到一个新的对象。从其他StackOverflow的问题示例 - http://stackoverflow.com/questions/78536/cloning-objects-in- ç

1) Use a technique to create a deep copy to a new object. Example from other StackOverflow Question - http://stackoverflow.com/questions/78536/cloning-objects-in-c

2)商品的XAML应用程序中的字符串,然后使用XAML读者创建路径的实例:

2) Store the XAML in strings within the application and then use the XAML reader to create instances of the Paths:

System.Windows.Shapes.Path newPath = (System.Windows.Shapes.Path)System.Windows.Markup.XamlReader.Parse("<Path xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'  Width='20' Height='80' Stretch='Fill' Fill='#FF000000' Data='M 20,25.2941L 20,29.4118L 15.9091,29.4118L 15.9091,40L 12.2727,40L 12.2727,29.4118L 2.54313e-006,29.4118L 2.54313e-006,25.6985L 13.4872,7.62939e-006L 15.9091,7.62939e-006L 15.9091,25.2941L 20,25.2941 Z M 12.2727,25.2941L 12.2727,5.28493L 2.09517,25.2941L 12.2727,25.2941 Z M 20,65.2941L 20,69.4118L 15.9091,69.4118L 15.9091,80L 12.2727,80L 12.2727,69.4118L -5.08626e-006,69.4118L -5.08626e-006,65.6985L 13.4872,40L 15.9091,40L 15.9091,65.2941L 20,65.2941 Z M 12.2727,65.2941L 12.2727,45.2849L 2.09517,65.2941L 12.2727,65.2941 Z ' HorizontalAlignment='Left' VerticalAlignment='Top' Margin='140,60,0,0'/>");
LayoutRoot.Children.Add(newPath);



3)只存储在资源字典的路径数据。 。在代码中创建一个路径的新实例,路径数据应用到新的路径,然后添加其他属性我感兴趣的是手动

3) Only store the Path data in the Resource Dictionary. Create a new instance of a Path in code, apply the Path data to the new Path and then add the other properties I am interested in manually.

该XAML - 路径数据存储为一个StreamGeometry:

The XAML - The Path data is stored as a StreamGeometry:

<UserControl.Resources>
    <ResourceDictionary>
        <StreamGeometry x:Key="N44">M 20,25.2941L 20,29.4118L 15.9091,29.4118L 15.9091,40L 12.2727,40L 12.2727,29.4118L 2.54313e-006,29.4118L 2.54313e-006,25.6985L 13.4872,7.62939e-006L 15.9091,7.62939e-006L 15.9091,25.2941L 20,25.2941 Z M 12.2727,25.2941L 12.2727,5.28493L 2.09517,25.2941L 12.2727,25.2941 Z M 20,65.2941L 20,69.4118L 15.9091,69.4118L 15.9091,80L 12.2727,80L 12.2727,69.4118L -5.08626e-006,69.4118L -5.08626e-006,65.6985L 13.4872,40L 15.9091,40L 15.9091,65.2941L 20,65.2941 Z M 12.2727,65.2941L 12.2727,45.2849L 2.09517,65.2941L 12.2727,65.2941 Z</StreamGeometry>
    </ResourceDictionary>
</UserControl.Resources>



中的C#代码然后创建一个实例,并将其他值:

The C# code to then create an instance and apply the other values:

System.Windows.Shapes.Path bPath = new System.Windows.Shapes.Path();
bPath.Data = (System.Windows.Media.Geometry)this.FindResource("N44");

bPath.Width = 20;
bPath.Height = 80;

bPath.VerticalAlignment = System.Windows.VerticalAlignment.Top;
bPath.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;

left = left + 40;

System.Windows.Thickness thickness = new System.Windows.Thickness(left,100,0,0);
bPath.Margin = thickness;

bPath.Fill = System.Windows.Media.Brushes.Black;
LayoutRoot.Children.Add(bPath);

这篇关于我怎样才能在运行时路径,已在XAML ResourceDictionary中被定义,多次添加到一个WPF形式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆