我已經閱讀了很多問題和答案來解決這個問題,但沒有找到任何有助于解決這個問題的東西。我試圖公開一個最小的例子,所以這不完全是我的真實代碼(如果其中有任何錯誤,請告訴我)。
我想做什么?我只是想創建一個使用泛型類的 UserControl。我想像 WPF 框架一樣使用它,我的意思是,我希望能夠將屬性系結到任何類的通用物件(Itemssource在 WPF 框架的情況下,您可以將其系結到ObservableCollection<AnyClass>)。
首先我定義我的類:
public class MyGenericClass<T> where T : IMyItemInterface
{
public ObservableCollection<T> MyOriginalList { get; set; }
public T MySelectedItem { get; set; }
... more code here ...
}
然后我創建一個 UserControl ( MyUserControl) ,其中包含此 DependencyProperty:
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} />
uj5u.com熱心網友回復:
型別的屬性,不能設定MyGenericClass<IMyItemInterface>一個MyGenericClass<MyClassItem>,因為MyGenericClass<MyClassItem>是不是一個MyGenericClass<IMyItemInterface>僅僅因為MyClassItem工具IMyItemInterface。
這稱為變體,C# 將變體型別引數限制為泛型介面和泛型委托型別。
例如,您可以將IEnumerable<object>欄位設定為 a,List<string>但不能將List<object>欄位設定為 a,List<string>盡管List<T>實作了IEnumerable<T>.
那是你的問題,為什么你的依賴屬性沒有設定,你的回呼沒有被呼叫。
請參閱此問題和答案以獲取更多資訊:
C# 方差問題:將 List<Derived> 分配為 List<Base>
關于協變和逆變的檔案也應該有所幫助。
uj5u.com熱心網友回復:
像這樣宣告依賴屬性型別可能就足夠了:
public class MyItemsList
{
public ObservableCollection<IMyItemInterface> MyOriginalList { get; set; }
public IMyItemInterface MySelectedItem { get; set; }
}
和這樣的依賴屬性:
public MyItemsList ItemsList
{
get { return (MyItemsList)GetValue(ItemsListProperty); }
set { SetValue(ItemsListProperty, value); }
}
public static readonly DependencyProperty ItemsListProperty =
DependencyProperty.Register(
nameof(ItemsList), typeof(MyItemsList), typeof(MyUserControl));
像這樣的分配(和等效的系結)現在可以作業了:
c.ItemsList = new MyItemsList { MySelectedItem = new MyClassItem() };
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/408085.html
標籤:
下一篇:分組單選按鈕
