具有多个类类型的单个组合C#列表

时间:2011-02-24 13:10:50

标签: c# .net wpf list

建立我在这里看到的帖子:

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;
    }
}

将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'不包含'Data'的定义,也没有扩展方法'Data'接受'CombinedClass'类型的第一个参数

您可以通过强制转换来访问Data成员,但是这会破坏这一点。

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

关于如何将列表与多个类类型组合并在WPF中绑定它们的任何想法

3 个答案:

答案 0 :(得分:3)

你的问题不是演员。问题是,ClassAClassBCombinedList返回List,而属性Data是列表中每个实例的属性!

此外,您的界面CombinedClass无用,因为它不提供任何内容。您应该在其中添加object Data之类的内容,并使用CombinedClass<T>关键字覆盖new中的属性。

总的来说,我不确定,这是一个好主意,即使它是相关问题中的公认答案。

答案 1 :(得分: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>

答案 2 :(得分: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>