使Polygon资源独一无二

时间:2016-03-25 17:44:09

标签: c# wpf

  

可能重复:
  WPF accesses only single instance of derived class with dependency property

我在XAML文件中将Polygon定义为UserControl的资源:

<UserControl.Resources>
    <Polygon x:Key="MyPolygon">
        <Polygon.Points>
            ...
        </Polygon.Points>
    </Polygon>
</UserControl.Resources>

并且想要创建此元素的多个(但是单独的)实例并将它们添加到Canvas。

Polygon polygon = (Polygon) this.Resources["MyPolygon"];
// ...
canvas.Children.Add(polygon);

通过重复运行上述代码再次添加多边形时,会引发以下错误:

  

指定的Visual已经是另一个Visual的子项或CompositionTarget的根。

可能的解决方案是:

  • 克隆Polygon,这不是最优雅的方式
  • 从代码生成多边形

是否有更好的解决方案可能会使用Resources属性(或某种可实例化的Polygon)?

2 个答案:

答案 0 :(得分:3)

XAML中的“可实例化多边形”将是一个模板,其中包含Polygon。无论您需要多边形,请在其中放置ContentControl并将模板应用于其中。

如果你在XAML中完成所有这些工作,而不是代码背后的生活,生活会轻松得多。

<UserControl.Resources>
    <DataTemplate x:Key="MyPolygonTemplate">
        <Polygon>
            <Polygon.Points>
            ...
            </Polygon.Points>
        </Polygon>
    </DataTemplate>
</UserControl.Resources>

<Grid>
    <Canvas>
        <ContentControl 
            ContentTemplate="{StaticResource MyPolygonTemplate}" 
            />
    </Canvas>
</Grid>

如果您需要创建任意数量的ItemsControl,请使用Canvas ItemsPanel,并在ItemTemplate中添加Polygon } ItemsControl。要填充ItemsControl,您需要将其ItemsSource绑定到您的viewmodel的ObservableCollection<T>属性。该集合将包含您的多边形内容可视化表示的任何数据项对象。如果你需要十个多边形飞来飞去,在收集和宾果游戏中加入十件东西,那就是它们。 Yank一出,UI将只显示其余九个。要定位它们,请将Canvas.LeftCanvas.Top绑定到数据项类的相应属性(必须实现INotifyPropertyChanged)(您可能必须通过an ItemContainerStyle应用这些属性;我没有用Canvas完成了很多工作。

如果没有必要,您实际上不必使用ContentControl的{​​{1}}属性。但是,如果您愿意,可以使用Content从数据项类中传递Content个不同的Polygon集。

这是一个常见问题的副本; I answered it yesterday too

答案 1 :(得分:2)

还有x:Shared ="false"

  

设置为 false 时,修改WPF资源检索行为,以便对属性资源的请求为每个请求创建一个新实例,而不是为所有请求共享同一个实例。