2011-02-24 11 views
2

要建立在一個職位,我在這裏看到:與多個類型單一組合C#列表

C# - Multiple generic types in one list

我想一個WPF DataGrid綁定到ClassAClassBCombinedList屬性是這樣的:

<DataGrid ItemsSource="{Binding ClassAClassBCombinedList.Data}" /> 

物業:

public List<CombinedClass> ClassAClassBCombinedList 
{ 
    get 
    { 
     List<CombinedClass> result = new List<CombinedClass>(); 
     result.Add(new CombinedClass<ClassA>(new ClassA())); 
     result.Add(new CombinedClass<ClassB>(new ClassB())); 
     return result; 
    } 
} 

With CombinedClass定義爲:

public interface CombinedClass { } 

public class CombinedClass<T> : CombinedClass where T : class 
{ 
    public CombinedClass(T classInstance) 
    { 
     Data = classInstance; 
    }    
    public T Data { get; private set; } 
} 

但是,這並不工作,因爲:
「CombinedClass」不包含對「數據」的定義和沒有擴展方法「數據」接受類型「CombinedClass」

的第一個參數

您可以通過投射來訪問數據成員,但這會破壞這一點。

((CombinedClass<ClassA>)ClassAClassBCombinedList.First()).Data; 

有關如何將列表與多個類類型組合並在WPF中綁定到他們的任何想法?

回答

3

你的問題不是演員。問題是,ClassAClassBCombinedList返回List,而屬性Data是列表中每個實例的屬性!

此外,您的接口CombinedClass是無用的,因爲它不提供任何內容。您應該在其中放入類似object Data的內容,並使用new關鍵字覆蓋CombinedClass<T>中的媒體資源。

總之,我不確定,這是一個好主意,儘管它是鏈接問題中的接受答案。

+0

對不起我的鏈接是錯誤的,我已經更新了。我使用空的CombinedClass接口(這可能很容易就是一個抽象類)的原因。這樣我就可以在不指定類類型的情況下創建一個CombinedClass列表。如果兩個類都是從基類派生出來的,那麼我在這裏做的事情會很容易,但它們不是。 – SDK 2011-02-24 13:35:29

+0

你是什麼意思,他們不是從一個基類派生。根據你的問題,他們是......他們來自CombinedClass。那是不正確的? – 2011-02-24 13:37:02

+0

@SDK:你的問題是,你試圖將'ClassAClassBCombinedList.Data'綁定到'ItemsSource',你應該只綁定'ClassAClassBCombinedList'。在ListView中的DataTemplate中,您可以訪問屬性Data。 – 2011-02-24 13:38:19

2

你爲什麼不使你的ClassAClassB使用相同的接口IClass定義了Data財產?然後,您可以製作List<IClass>,其中可以包含ClassA以及ClassB,您可以將其綁定到DataGrid

public interface IClass 
{ 
object Data {get; set; } 
} 

public class ClassA : IClass 
{ 
// implement `Data` property 
} 

public class ClassB : IClass 
{ 
// implement `Data` property 
} 


{ 
// make the list by adding objects of type `ClassA` or `ClassB`, don't forget to set their `Data` property 
List<IClass> result = new List<IClass>(); 
result.Add(new ClassA()); 
result.Add(new ClassB()); 
} 

,並將其綁定

dataGrid.ItemsSource = result // List<IClass> 
+0

這將工作得很好,但是ClassA和ClassB已經從不同的基類派生出來了,我無權改變它們。 – SDK 2011-02-24 13:47:25

+1

他們是部分類嗎?如果是這樣,你可以使用接口使用相同的名稱創建另一個partial:'public partial class ClassA:IClass {}'。編譯完成後,您無法更改的'ClassA'仍然使用該接口,並且我的方法可以在不編輯現有'ClassA'的情況下工作。 – Bazzz 2011-02-24 13:49:07

+0

不幸的是,他們不是。 – SDK 2011-02-24 13:54:56

0

您可這得太多。

爲什麼不只是創建一個List<object>並用你需要在UI中顯示的任何對象填充它?然後這樣做:

<ListBox ItemsSource="{Binding MyList}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
     <TextBlock Text="{Binding Data}"/> 
     </DataTemplate> 
    </ListBox.Template> 
</ListBox> 

如果ClassAClassB不共享公共屬性,你可以這樣做:

<ListBox ItemsSource="{Binding MyList}"> 
    <ListBox.Resources> 
     <DataTemplate TargetType="{x:Type local:ClassA}"> 
     <!-- template for ClassA objects --> 
     </DataTemplate> 
     <DataTemplate TargetType="{x:Type local:ClassB}"> 
     <!-- template for ClassB objects --> 
     </DataTemplate> 
    </ListBox.Resources> 
</ListBox>