我对不能通过XAML为Canvas.Children设置绑定感到有点惊讶。我不得不求助于代码隐藏方法,如下所示:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
DesignerViewModel dvm = this.DataContext as DesignerViewModel;
dvm.Document.Items.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Items_CollectionChanged);
foreach (UIElement element in dvm.Document.Items)
designerCanvas.Children.Add(element);
}
private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
ObservableCollection<UIElement> collection = sender as ObservableCollection<UIElement>;
foreach (UIElement element in collection)
if (!designerCanvas.Children.Contains(element))
designerCanvas.Children.Add(element);
List<UIElement> removeList = new List<UIElement>();
foreach (UIElement element in designerCanvas.Children)
if (!collection.Contains(element))
removeList.Add(element);
foreach (UIElement element in removeList)
designerCanvas.Children.Remove(element);
}
我更愿意在XAML中设置一个绑定,如下所示:
<Canvas x:Name="designerCanvas"
Children="{Binding Document.Items}"
Width="{Binding Document.Width}"
Height="{Binding Document.Height}">
</Canvas>
有没有一种方法可以在不采用代码隐藏方法的情况下实现这一点?我已经做了一些关于这个主题的谷歌搜索,但对于这个特定的问题还没有想出太多。
我不喜欢我现在的方法,因为它搞砸了我漂亮的模型-视图-视图模型,因为它让视图知道它的ViewModel。
发布于 2009-05-20 20:05:07
我不相信将绑定与Children属性一起使用是可能的。我今天真的试着这么做了,但我犯了错误,就像对你一样。
画布是一个非常初级的容器。它真的不是为这种工作而设计的。您应该研究众多ItemsControls中的一个。您可以将ViewModel的ObservableCollection数据模型绑定到它们的ItemsSource属性,并使用DataTemplates来处理如何在控件中呈现每个项。
如果找不到以令人满意的方式呈现项目的ItemsControl,则可能需要创建一个自定义控件来执行所需的操作。
发布于 2009-06-23 01:18:19
<ItemsControl ItemsSource="{Binding Path=Circles}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="White" Width="500" Height="500" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Fill="{Binding Path=Color, Converter={StaticResource colorBrushConverter}}" Width="25" Height="25" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
<Setter Property="Canvas.Left" Value="{Binding Path=X}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
发布于 2009-07-30 21:57:06
其他人已经给出了可扩展的回复,告诉你如何做你实际上已经想做的事情。我只会解释为什么不能直接绑定Children
。
问题很简单-数据绑定目标不能是只读属性,而Panel.Children
是只读的。那里没有对集合的特殊处理。相反,ItemsControl.ItemsSource
是一个读/写属性,即使它是集合类型--这在.NET类中很少见,但为了支持绑定场景,它是必需的。
https://stackoverflow.com/questions/889825
复制相似问题