C# 绑定到IEnumerable依赖项属性

C# 绑定到IEnumerable依赖项属性,c#,wpf,dependency-properties,C#,Wpf,Dependency Properties,我创建了一个自定义控件,名为SearchableCheckBoxList,它源自UserControl。在此控件中,我有一个ItemsControl,其中包含Entry类型的项,如下所定义: public class Entry : BindableBase { public Entry(object content) : this(content, false) { } public Entry(object content, bool isCheck

我创建了一个自定义控件,名为SearchableCheckBoxList,它源自UserControl。在此控件中,我有一个ItemsControl,其中包含Entry类型的项,如下所定义:

public class Entry : BindableBase
{
    public Entry(object content)
        : this(content, false)
    { }

    public Entry(object content, bool isChecked)
    {
        Content = content;
        IsChecked = isChecked;
    }

    private bool _isChecked;
    public bool IsChecked
    {
        get { return _isChecked; }
        set { this.SetProperty(ref this._isChecked, value); }
    }

    private object _content;
    public object Content
    {
        get { return _content; }
        set { SetProperty(ref _content, value); }
    }

}
在我的代码隐藏中,我还有一个名为ItemsSource的IEnumerable类型的DependencyProperty,它接受任何类型的项集合,并将它们转换为条目类型。也就是说,对于集合中的每个元素,我将创建一个新的条目项,并将该元素存储在条目项的Content属性中,如下所示:

foreach (var item in ItemsSource)
   itemsControl.Items.Add(new Entry(item));
我这样做是因为在我的ItemsControl中,每个项目旁边都有一个复选框,用户可以单击一个或多个复选框来选择多个项目,这些项目将反映在每个条目项目的IsChecked属性上

我的代码隐藏中还有另一个依赖项属性,名为SelectedItems,定义如下:

public IEnumerable<object> SelectedItems
{
    get { return (IEnumerable<object>)GetValue(SelectedItemsProperty); }
    set { SetValue(SelectedItemsProperty, value); }
}
public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register("SelectedItems", typeof(IEnumerable<object>), typeof(SearchableCheckBoxList), 
                                                                    new PropertyMetadata(default(IEnumerable<object>)));
private ObservableCollection<CityModel> _cityCollection;
public ObservableCollection<CityModel> CityCollection
{
    get { return _cityCollection; }
    set { SetProperty(ref _cityCollection, value); }
}

private List<object> _selectedCities = new List<object>();
public List<object> SelectedCities
{
    get { return _selectedCities; }
    set { SetProperty(ref _selectedCities, value); }
}
控件看起来像

现在,所有这些都可以正常工作,绑定正在按预期更新。我遇到的问题是,要使其工作,必须将选定的城市定义为列表。我想将SelectedCities定义为List,但如果我这样做,我的属性的setter总是以null值调用。我似乎不明白为什么或者怎么做


按要求编辑,这里是和

我相信您的问题是C语言中的集合不是协变的。 我的意思是你不能把列表转换成列表


你能让条目通用吗?是的。正是这样,它将保持强类型。我会这样做,让你知道什么happens@DanielA.White我将条目设置为通用条目,但在我的SearchableCheckBoxList.cs中,当我尝试创建条目类型的项目时,它当然会要求输入类型,控件不知道的地方。@kyriacos_k您能在哪里分享您的整个项目吗?谢谢。我明白你的意思,但是拥有一个基类接口并不是一个理想的情况,因为我想要使用它的任何模型都必须实现它。我希望有一个更好的解决方案。正如你们在问题中看到的,使用泛型也是有问题的comments@kyriacos_k老实说我不确定有没有完美的解决方案,这就是为什么我在我的代码中显式地指定DependencyProperties的类型,毕竟propdp代码段的语法没有问题,而且您重用的也不多。我将等待,看看是否有人有更好的solution@netaholic我尝试使用您的界面建议作为临时解决方案。我的类是从ISelectableBase派生的,我的SelectedItems是IEnumerable类型。绑定不起作用,但是,我的属性setter中的值始终为null
<controls:SearchableCheckBoxList SelectedItems="{Binding SelectedCities, Mode=TwoWay}"
                                 ItemsSource="{Binding CityCollection, Mode=OneTime}"/>                       
private ObservableCollection<CityModel> _cityCollection;
public ObservableCollection<CityModel> CityCollection
{
    get { return _cityCollection; }
    set { SetProperty(ref _cityCollection, value); }
}

private List<object> _selectedCities = new List<object>();
public List<object> SelectedCities
{
    get { return _selectedCities; }
    set { SetProperty(ref _selectedCities, value); }
}
class Program
{
    static void Main(string[] args)
    {
        List<object> foo = new List<object>();
        List<Person> bar = new List<Person>();

        List<object> some = (List<object>) bar;
    }

    class Person { }
}
 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var control = new myUserControl();
            myPersons = new List<Person>() { new Person() { Name = "some" } };
            control.SetBinding(myUserControl.MyPropertyProperty, new Binding() { Source = MyPersons });
        }

        private List<Person> myPersons { get; set; }
        public List<Person> MyPersons { get { return myPersons; } set { myPersons = value; } }
    }

    public class Person { public string Name; }

    public class myUserControl : UserControl
    {
        public object MyProperty
        {
            get { return (object)GetValue(MyPropertyProperty); }
            set { SetValue(MyPropertyProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyPropertyProperty =
            DependencyProperty.Register("MyProperty", typeof(object), typeof(myUserControl), new PropertyMetadata(0));
    }