【发布时间】:2022-01-07 11:03:48
【问题描述】:
我已经阅读了很多问题和答案来解决这个问题,但没有找到任何有助于解决这个问题的东西。我试图公开一个最小的例子,所以这不是我真正的代码(如果其中有任何错误,请告诉我)。
我想做什么?我只是想创建一个使用泛型类的 UserControl。我想像 WPF 框架一样使用它,我的意思是,我希望能够将属性绑定到任何类的通用对象(在 WPF 框架案例中为Itemssource,您可以将其绑定到ObservableCollection<AnyClass>)。
首先我定义我的类:
public class MyGenericClass<T> where T : IMyItemInterface
{
public ObservableCollection<T> MyOriginalList { get; set; }
public T MySelectedItem { get; set; }
... more code here ...
}
然后我创建一个包含此 DependencyProperty 的 UserControl (MyUserControl):
public partial class MyUserControl: UserControl
{
... code here ...
public static readonly DependencyProperty ItemsListProperty =
DependencyProperty.Register("ItemsList", typeof(MyGenericClass<IMyItemInterface>),
typeof(MyUserControl),
new FrameworkPropertyMetadata(new PropertyChangedCallback(OnItemsListChanged)));
private static void OnItemsListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MyUserControl myControl = (MyUserControl)d; // just for debugging
}
public MyGenericClass<IMyItemInterface> ItemsList
{
get => (MyGenericClass<IMyItemInterface>)GetValue(ItemsListProperty);
set => SetValue(ItemsListProperty, value);
}
... more code here ...
}
此代码可以编译,但不起作用。如果我在OnItemsListChanged 中设置断点,它永远不会触发。
我可以通过这种方式将typeof(MyGenericClass<IMyItemInterface>) 更改为typeof(object):
public static readonly DependencyProperty ItemsListProperty =
DependencyProperty.Register("ItemsList", typeof(object),
typeof(MyUserControl),
new FrameworkPropertyMetadata(new PropertyChangedCallback(OnListaItemsChanged)));
现在它确实触发了OnItemsListChanged,但现在我在get => (MyGenericClass<IMyItemInterface>)GetValue(ItemsListProperty); 中有一个强制转换异常,这是合乎逻辑的,因为 MyGenericClass 派生自对象而不是来自 MyGenericClass 的对象。所以我也尝试将属性更改为:
public object ItemsList
{
get => GetValue(ItemsListProperty);
set => SetValue(ItemsListProperty, value);
}
现在它再次编译并继续触发OnItemsListChanged,但现在我不能使用 ItemList 做任何事情,因为我不能引用ItemLists.MySelectedItem(例如),因为MySelectedItem 在object 类中不存在。
问题是:什么是正确的方法?我做错了什么?
更新:
我绑定到ItemsList 的是MyGenericClass 的一个实例。例如,我有一个实现 IMyItemInterface (MyClassItem) 的类,在代码隐藏MyGenericClass<MyClassItem> myItem = new(); 中执行后,我以这种方式在 XAML 中绑定:
<MyCustomControl ItemsList={Binding myItem, Mode=TwoWay} />
【问题讨论】:
-
MyGenericClass 是否应该是 IEnumerable 或 ICollection 或 IList?比使用 IEnumerable/ICollection/IList 作为依赖属性的类型。还要说明为什么你的 UserControl 应该实现 INotifyPropertyChanged。这对依赖属性毫无意义。
-
@Clemens 你是对的,INotifyPropertyChanged 对依赖属性毫无意义,我编辑不是问题并将其删除。关于另一个问题,不,它不是 IEnumerable,但它具有 IEnumerable 内部的属性。我更新了这个问题。谢谢
-
输出窗口中是否有任何绑定错误?
-
@Carlos:您将
ItemsList属性设置或绑定到什么? -
@mm8 我已使用此信息更新了问题。谢谢
标签: c# wpf dependency-properties