【问题标题】:WPF ListBox - combine 2 tables for one listWPF ListBox - 为一个列表组合 2 个表
【发布时间】:2021-10-01 21:02:51
【问题描述】:

我有 2 张桌子,桌子 A 和桌子 B。 我想要一个列表框,其中包含两个表中的数据,如下所示:

 <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal">
          <TextBlock Text="{Binding Path=[field_name]}"/>
      </StackPanel>
     </DataTemplate>
 </ListBox.ItemTemplate>

其中 field_name 将首先是 A.someFieldName,然后是 B.someOtherFieldName(两个名称不同!)

是否可以使用 WPF?

谢谢!

【问题讨论】:

  • 从技术上讲,您可以在 ListBox 中有两列。但是使用 ListView 可能是一个更好的主意:docs.microsoft.com/en-us/dotnet/desktop/wpf/controls/…
  • 要使用两个表作为数据源吗?这是不可能的。在将它们用作数据源之前,您必须先组合这些表。
  • 有一个叫做MultiBinding的东西,但是解决你的问题是否是个好主意......取决于你在做什么。不确定它是否适用于列表。 stackoverflow.com/questions/2552853/…
  • @PEK 是可能的,使用复合集合。

标签: c# database wpf visual-studio listbox


【解决方案1】:

您可以添加两个 DataTemplate 资源,AB 每种类型一个,没有 x:Key,只有 DataType,因此它们被隐式用作默认模板。双重收集的事情可以由CompositeCollection处理。

这是它的工作原理:

<ListBox>
        <ListBox.Resources>
            <CollectionViewSource x:Key="ListOfA" Source="{Binding ListOfA}"/>
            <CollectionViewSource x:Key="ListOfB" Source="{Binding ListOfB}"/>
            <DataTemplate DataType="{x:Type local:A}">
                <TextBlock Text="{Binding Path=Name }"/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type local:B}">
                <TextBlock Text="{Binding Path=Value}"/>
            </DataTemplate>
        </ListBox.Resources>
        <ListBox.ItemsSource>
            <CompositeCollection>
                <CollectionContainer Collection="{Binding Source={StaticResource ListOfA}}" />
                <CollectionContainer Collection="{Binding Source={StaticResource ListOfB}}" />
            </CompositeCollection>
        </ListBox.ItemsSource>
    </ListBox>

ViewModel(仅用于演示)=> ListBox 的 DataContext

public class MainViewModel
    {
        public MainViewModel (){
            ListOfA = new List<A> { new A { Name  = "Susi" }, new A { Name = "Bertie" }, new A { Name = "Anna" } };
            ListOfB = new List<B> { new B { Value = 600 }, new B { Value   = 700 }, new B { Value     = 1000 } };
        }

        public List<A> ListOfA { get; }
        public List<B> ListOfB { get; }
    }

    public class A
    {
        public string Name { get; set;}
    }
    public class B
    {
        public int Value { get; set; }
    }

【讨论】:

  • 我一直在尝试遵循您的回答,但我很难将其与我的情况相适应。我的 2 个列表取自 db (Oracle sql),每个列表都是 DataRows 列表。所以现在,如果我有 2 个单独的 ListBox,我使用 {Binding Path=["A"]} 绑定它们,其中 A 是数据库中某行的名称
  • 如果两个列表属于同一类型 (DataRow),则不会像我的示例那样工作。您仍然可以使用ItemTemplateSelector 为每个列表提供一个模板。作为初学者,此链接可能会有所帮助..:docs.microsoft.com/en-us/dotnet/api/… 我不知道这是否容易理解。项目模板选择器分析每个“项目”即行的数据。根据项目数据,它返回项目模板 A 或 B(或 C)。由您来定义开关/标准。
猜你喜欢
  • 2014-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-15
相关资源
最近更新 更多