一尘不染

是否可以在XAML中绑定Canvas的Children属性?

c#

我无法通过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>

是否有一种无需借助代码隐藏方法即可完成此任务的方法?我已经对该主题进行了一些搜索,但是对于这个特定问题并没有提出太多建议。

我不喜欢我当前的方法,因为它通过使View知道它是ViewModel来欺骗我很好的Model-View-ViewModel。


阅读 310

收藏
2020-05-19

共1个答案

一尘不染

我不认为可以将绑定与Children属性一起使用。实际上,我今天确实尝试过这样做,但它像您所做的那样使我感到错误。

画布是一个非常基本的容器。确实不是针对此类工作而设计的。您应该查看许多ItemsControls之一。您可以将ViewModel的ObservableCollection数据模型绑定到其ItemsSource属性,并使用DataTemplates处理控件中每个项目的呈现方式。

如果找不到能够令人满意地渲染项目的ItemsControl,则可能必须创建一个满足您需要的自定义控件。

2020-05-19