2010-02-23 242 views
10

在我的WPF应用程序中,我有一个Canvas,在其中绘制一些图形。早些时候,我在后面的代码中处理了绘图,但现在我已将所有事情都考虑到了ViewModel。这给我一些挑战..将WPF Canvas子项绑定到ObservableCollection

我有几个InkPresenter对象持有笔画。 Earier我加入他们的孩子到画布后面的代码 - 这样的:

// Build an InkPresenter: 
var someInkPresenter = BuildInkPresenter(..); 
//_myCanvas is the <Canvas> I want to display it in: 
_myCanvas.Children.Add(someInkPresenter); 

现在 - 不是建设持有_myCanvas我需要以不同的方式做到这一点的XAML的代码隐藏InkPresenter。我想要做的是创造一个InkPresenter并将其添加到集合:现在

public ObservableCollection<InkPresenter> Drawings; 

我的问题是如何将画布绑定到这个的ObservableCollection - 并有当添加到集合中的InkPresenters显示。我可以使用数据绑定以某种方式实现这一点吗?

回答

16

我想你可以用ItemsControl + ItemsPanelTemplate做到这一点。就像这样:

<ItemsControl ItemsSource="{Binding YourCollection}"> 
    <ItemsControl.ItemsPanel> 
    <ItemsPanelTemplate> 
     <Canvas /> 
    </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    </ItemsControl> 

想了解更多关于这种方法是指Dr.WPF:ItemsControl: A to ZP is for Panel

+0

Thx!听起来很合理。将看看它! – stiank81 2010-02-23 11:56:40

+1

这通常是您要采取的方法,但在这种情况下您可能会遇到问题,因为InkPresenter不会像Canvas那样直接作为子代,就像它们在代码中添加它们时一样。相反,Visual Tree将在每个InkPresenter项目周围注入一个额外的ContentPresenter。为了使这种方法起作用,您应该查看每个InkPresenter的实际数据(Strokes),并将这些数据存储在您的VM中。然后,您可以创建一个覆盖GetContainerForItemOverride以返回InkPresenter的自定义ItemsControl。 – 2010-02-23 17:17:04

+0

不能同意你约翰...这是一个ItemsControl。它使用UIElement作为默认容器... – Anvaka 2010-02-23 17:46:05

10

Anvaka提出的解决方案是伟大的,但约翰·博文指出,你需要知道的多一点,如果你想实际将你的项目绑定到Canvas附加属性。

下面是关于如何绑定到Canvas.Left和Canvas.Top一个例子:

<ItemsControl ItemsSource="{Binding YourCollection}"> 
<ItemsControl.ItemsPanel> 
    <ItemsPanelTemplate> 
     <Canvas /> 
    </ItemsPanelTemplate> 
</ItemsControl.ItemsPanel> 
<ItemsControl.ItemContainerStyle> 
    <Style TargetType="ContentPresenter"> 
     <Setter Property="Canvas.Left" Value="{Binding YourModelLeft}" /> 
     <Setter Property="Canvas.Top" Value="{Binding YourModelTop}" /> 
    </Style> 
</ItemsControl.ItemContainerStyle> 

顺便说一句,我找到了解决办法上this question后,我试图Anvaka的建议,其中结合不工作。

希望这可以帮助他人,寻找相同的答案。

+0

谢谢,正是我在找的东西。 – Cousken 2016-05-12 10:56:08

相关问题