首页 > 解决方案 > 如何将子类型的集合绑定到依赖属性

问题描述

我在 WPF 中创建了一个 UserControl,它可以用于任何类型的对象IMyNode。基本上,它通过依赖属性接收 ObservableCollection,注册到它并做一些事情。

在我的一个用例中,我在一个使用(并且需要)的控件中使用了一个 ObservableCollection SomeSpecificNodeSomeSpecificNode是一个实现IMyNode

目前,我有一个绑定错误:

System.Windows.Data Error: 1 : Cannot create default converter to perform 'one-way' conversions between types 'System.Collections.ObjectModel.ObservableCollection`1[SomeSpecificNode]' and 'System.Collections.ObjectModel.ObservableCollection`1[IMyNode]'. 

我理解它为什么会发生,它不知道如何自动转换ObservableCollection<SomeSpecificNode>ObservableCollection<IMyNode>.

这样做的正确方法是什么?

使用转换器会破坏NotifyPropertyChange. 在我的父 ViewModel 中使用 aObservableCollection<IMyNode>不适用于同一页面中的其他控件。

谢谢!

这里有一些伪代码:

public class SomeSpecificNode: IMyNode{
}
public interface IMyNode{

}



public class ParentViewModel {
    public ObservableCollection<SomeSpecificNode> SelectedNodes {get;}=> new ObservableCollection<SomeSpecificNode>()

}


<UserControl x:Class="ParentView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ch.VibroMeter.Xms.Configurators.Controls.ActionBar"
             xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.DataContext>
        <ParentViewModel/>
    </UserControl.DataContext>
    <StackPanel Orientation="Horizontal" Name="RootContainer">
        <SomeChildControl Nodes="{Binding SelectedNodes}" /><!-- This binding will fail !-->
    </StackPanel
</UserControl>



public partial class ParentView : UserControl
{
        public static readonly DependencyProperty NodesProperty = DependencyProperty.Register(
            nameof(Nodes), typeof(ObservableCollection<IMyNode>), typeof(ParentView), new PropertyMetadata(default(ObservableCollection<IMyNode>), OnNodesChanged));

        private static void OnNodesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //...
        }

        public  ObservableCollection<IMyNode>  Nodes
        {
            get { return (ObservableCollection<IMyNode>)GetValue(NodesProperty); }
            set { SetValue(NodesProperty, value); }
        }
}

标签: wpfxamlmvvmbinding

解决方案


您应该将依赖属性的类型更改为兼容的类型,例如IEnumerable<IMyNode>.

您不能将属性设置为orObservableCollection<IMyNode>以外的任何内容。ObservableCollection<IMyNode>null

AnObservableCollection<SomeSpecificNode>不是anObservableCollection<IMyNode>它是一个实现的IEnumerable<IMyNode>假设。SomeSpecificNodeIMyNode

所以这编译得很好;

IEnumerable<IMyNode> collection = new ObservableCollection<SomeSpecificNode>();

但这不会:

ObservableCollection<IMyNode> collection = new ObservableCollection<SomeSpecificNode>(); //Cannot implictly convert type...

不同之处在于它IEnumerable<T>是协变的。请参阅文档以获取更多信息。


推荐阅读