C# 寻求建议:将收集管理责任委托给不需要';我不知道所涉及的数据类型
我有3个框负责显示3种数据的名称,例如: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的容器窗口中添加任何代码,但数据本身是该容器窗口的一部分 问题在于
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); }
}