C# 寻求建议:将收集管理责任委托给不需要';我不知道所涉及的数据类型

C# 寻求建议:将收集管理责任委托给不需要';我不知道所涉及的数据类型,c#,wpf,design-patterns,mvvm,C#,Wpf,Design Patterns,Mvvm,我有3个框负责显示3种数据的名称,例如: class Shake { ... } class Molecule { ... } class Existence { ... } 它们都出现在一个可观察集合中: public ObservableCollection<Shake> Shakes { get; set; } ... 整个想法是UserControl负责从列表中删除项目-我不需要在这些UserControl的容器窗口中添加任何代码,但数据本身是该容器窗口的一部分 问题在于

我有3个框负责显示3种数据的名称,例如:

class Shake { ... }
class Molecule { ... }
class Existence { ... }
它们都出现在一个
可观察集合中

public ObservableCollection<Shake> Shakes { get; set; }
...
整个想法是
UserControl
负责从列表中删除项目-我不需要在这些
UserControl
的容器
窗口中添加任何代码,但数据本身是该容器
窗口的一部分

问题在于:当
用户控件
需要删除项时,它不知道该项的类型(它有一个
可观察集合
,而不是
可观察集合
),因此此代码失败:

private void RemoveElementButton_OnClick(object sender, RoutedEventArgs e) {
    for (var i = TheListBox.SelectedItems.Count - 1; i >= 0; i--)
        ItemsSource.RemoveAt(i);
}
因为
ItemsSource
属性(附在上面)试图将
observedcollection
强制转换为
observedcollection
。。。目前我有:

 private void RemoveElementButton_OnClick(object sender, RoutedEventArgs e) {
    for (var i = TheListBox.SelectedItems.Count - 1; i >= 0; i--)
     (GetValue(ItemsSourceProperty) as dynamic).RemoveAt(i);
}
但我不太喜欢它(如果我在将来某一天将
observateCollection
更改为
NewDotNet7AwesomeCollection
),会怎么样


现在让我们假设我没有3个盒子,但是33个。。。您有什么建议(顺便说一句,集合可以从外部更改,因此,
observateCollection
在这里是必不可少的)?

您可以为您的数据类型创建一个简单的基类。您可以在其中实现
INotifyPropertyChanged
接口,这样就不必在每个数据类型中:

class Shake : BaseDataType { ... }
class Molecule : BaseDataType { ... }
class Existence : BaseDataType { ... }
现在,您的
DependencyProperty
可以是此基本类型的集合:

public static readonly DependencyProperty ItemsSourceProperty =
    DependencyProperty.Register("ItemsSource", 
    typeof(ObservableCollection<BaseDataType>), typeof(ListWithTitle), 
    new PropertyMetadata(default(IEnumerable)));

public ObservableCollection<BaseDataType> ItemsSource {
    get { return (ObservableCollection<BaseDataType>)GetValue(ItemsSourceProperty); }
    set { SetValue(ItemsSourceProperty, value); }
}
那么您在删除项目时应该不会遇到任何问题:

ItemsSource.RemoveAt(i);

详细阐述我的评论:

改为创建IList类型的DP。源集合仍然可以是 可观察到的收集,仍然可以与IList结合。这样你就不会 我不得不担心打字

你有一个问题:

这是我正在寻找的方向,但如果我这样做,我会 我还能对可观察到的收集事件做出反应吗

根据我的理解,您的意思是询问,如果您将此DP与
ObservableCollection
绑定,您是否仍会收到
INotifyCollectionChanged
事件的通知,即在源列表中添加/删除对象时的GUI更新

是的,只要源集合实现INotifyCollectionChanged(或者在您的情况下说
ObservableCollection
),GUI就会正确响应事件

由于
ItemsControl
本身的
ItemsSource
属性属于
IEnumerable
类型,并且它仍然对INCC事件做出响应,因此这肯定会起作用。所以,在你的情况下,它也会起作用


公共静态只读依赖项属性项资源属性=
从属财产登记簿(“项目来源”,类型(IList),
类型(带标题的列表);
公共IList项目资源
{
get{return(ObservableCollection)GetValue(ItemsSourceProperty);}
set{SetValue(ItemsSourceProperty,value);}
}

PS-我建议将
IList
置于
IEnumerable
之上,因为根据您对该属性的使用情况-
ItemsSource.RemoveAt(I)。您需要索引并删除IList可用而IEnumerable上不可用的方法。否则,您必须像下面这样显式地将类型转换为IList(ItemsSource作为IList)。因此,这就是您想要选择IList或IEnumerable的调用。

创建类型为
IList
的DP。源集合仍然可以是
可见集合
,并且仍然可以与
IList
绑定。这样你就不必担心排版了。为什么它必须是
可观察的集合
?只要让它
Shake
@RohitVats-这就是我要寻找的方向,但如果我这样做,我还能对
observateCollection
事件做出响应吗?@lll-但我需要一个项目集合,我不想强迫用户继承
Shake
或创建包含集合的自定义类型,我想坚持一贯的做法conventions@Tal-我在回答中补充了更多的细节。看看这是否是你想要的。这个解决方案没有遵循
WPF
关于集合绑定的常规约定-我将无法绑定到
observedcollection
,其中
NonBaseDataType
不会继承
BaseDataType
我不知道你所指的是WPF的哪些常规约定。。。也许你能给我一个链接?当然,您不能将不扩展基类的元素添加到该基类类型的集合中。。。这是基本的泛型,与WPF的常规约定无关。
<ListBox ItemsSource="{Binding ItemsSource RelativeSource={RelativeSource 
    AncestorType={x:Type YourLocalPrefix:ListWithTitle}}}" ... />
ItemsSource.RemoveAt(i);
public static readonly DependencyProperty ItemsSourceProperty =
    DependencyProperty.Register("ItemsSource", typeof(IList), 
                                typeof(ListWithTitle));

public IList ItemsSource
{
    get { return (ObservableCollection<object>)GetValue(ItemsSourceProperty); }
    set { SetValue(ItemsSourceProperty, value); }
}