将 wpf listview 绑定到数据集......可能......?

Posted

技术标签:

【中文标题】将 wpf listview 绑定到数据集......可能......?【英文标题】:Binding a wpf listview to a Dataset....Possible..? 【发布时间】:2010-11-01 00:06:21 【问题描述】:

我正在努力迁移到 Wpf,我只是在尝试将数据绑定到 lsitview 时卡住了。我想将列表视图数据绑定到数据集(数据集,因为我想在列中显示的数据属于不同的表)。我是附上我正在尝试使用的示例代码。它工作正常,但列表只显示一行。可能是错的。任何人都可以指导我完成。所有可用的示例都使用数据表。没有指定绑定到数据集。请帮助..任何输入将不胜感激...提前致谢

我的 Xaml

<Grid>
<TextBox Text="" Height="20" Width="100" HorizontalAlignment="Left" Margin="15,13,0,0" VerticalAlignment="Top"></TextBox>
<TextBox Text="" Height="20" Width="100" HorizontalAlignment="Left" Margin="15,42,0,0" VerticalAlignment="Top"></TextBox>
<ListView Margin="15,89,63,73" Name="lst" ItemsSource="Binding">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name"  DisplayMemberBinding="Binding Path=T1/Name"></GridViewColumn>
            <GridViewColumn Header="Place" DisplayMemberBinding="Binding Path=T2/Name"></GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>
<!--<Button Height="19" HorizontalAlignment="Right" Name="button2" VerticalAlignment="Top" Width="46" Margin="0,42,63,0" Click="button2_Click">Add</Button>-->
<Button Height="19" HorizontalAlignment="Right" Name="button1" VerticalAlignment="Top" Width="46" Click="button1_Click" Margin="0,43,63,0">Add</Button>

我的代码

 Dt1 = new DataTable("T1");
        Dt1.Columns.Add("Name");
        Dt1.Rows.Add("abc1");
        Dt1.Rows.Add("abc2");
        Dt2 = new DataTable("T2");
        Dt2.Columns.Add("Name");
        Dt2.Rows.Add("xyz1");
        Dt2.Rows.Add("xyz1");
        Ds = new DataSet();
        Ds.Tables.Add(Dt1);
        Ds.Tables.Add(Dt2);

        lst.DataContext = Ds;

【问题讨论】:

【参考方案1】:

您好,我完全同意安迪和托马斯的看法。他们都优雅地解释了这个概念。

我只展示了仅使用 dataset 执行相同操作的步骤。

MVVM(ModelView ViewModel)我这里不讨论了。

Xaml 看起来像这样

<Grid Name="myGrid" ShowGridLines="False">


    <Label Height="28" Margin="12,5,0,0" Name="lblName" VerticalAlignment="Top" HorizontalAlignment="Left" Width="55">Name</Label>
    <TextBox Height="23" Margin="73,8,85,0" Name="txtName" VerticalAlignment="Top" />
    <Label Height="28" Margin="12,39,0,0" Name="lblPlace" VerticalAlignment="Top" HorizontalAlignment="Left" Width="55">Place</Label>
    <TextBox Height="23" Margin="73,44,85,0" Name="txtPlace" VerticalAlignment="Top" />
    <Button Height="23" HorizontalAlignment="Left" Margin="20,82,0,0" Name="btnAddRecord" VerticalAlignment="Top" Width="75" Click="btnAddRecord_Click">Add Record</Button>
    <ListView Margin="31,119,27,45" Name="listView" *ItemsSource="Binding"*>

        <ListView.View>

            <GridView>

                <GridViewColumn Header="Name"  DisplayMemberBinding="Binding Name"/>

                <GridViewColumn Header="Place" DisplayMemberBinding="Binding Place"/>


            </GridView>
        </ListView.View>
    </ListView>
</Grid>

在 .CS 文件中创建一个数据集

private DataSet MyDataSet()
    
        DataTable dtInformation1 = new DataTable();
        dtInformation1.Columns.Add("Name");
        dtInformation1.Columns.Add("Place");
        dtInformation1.Rows.Add(txtName.Text, txtPlace.Text);


        DataTable dtInformation2 = new DataTable();
        dtInformation2.Columns.Add("Name");
        dtInformation2.Columns.Add("Place");
        dtInformation2.Rows.Add(txtName.Text + "2", txtPlace.Text + "2");

        DataSet Ds = new DataSet();
        Ds.Tables.Add(dtInformation1);
        Ds.Tables.Add(dtInformation2);
        return Ds;
    

接下来在Button的点击事件中写下如下

private void btnAddRecord_Click(object sender, RoutedEventArgs e)

    

        **listView.ItemsSource = MyDataSet().Tables[0].DefaultView;
              - OR - 
         listView.ItemsSource = MyDataSet().Tables[1].DefaultView;**
    

注意~您不能将 ListView 的源分配给数据集。

为什么?你可能会问? 数据集,简单来说,就是数据表的集合。

假设您有 5 个不同的数据表。并说它们的列名和列号都不相同。

现在您已将所有这些分配给您的数据集。控件源如何知道它必须绑定哪个源?

为了克服这种情况,要么制作一个自定义数据表,其中包含这些离散数据表的所有列,并将值分配给这个自定义数据表,然后绑定到源。

或者你需要在数据源中显式指定数据表

但我总是更喜欢使用 MVVM 模式进行此类操作。

【讨论】:

"listView.DataContext = MyDataTable().Tables[0];" => 为什么? MyDataTable 返回一个 DataTable,而不是 DataSet... 不小心发生了。我应该写 mydataset().Tables[0] . 但是仍然无法将数据集绑定到列表视图或列表框..?.我只想在列表框中显示来自多个数据表的数据..U 可以绑定到对象。数据集和数据表是对象。那么绑定到业务对象和数据集有什么区别..?【参考方案2】:

我不确定你想在这里做什么......这是你期望的结果吗?

abc1    xyz1
abc2    xyz2

您的表之间没有关系,因此绑定系统无法猜测您要关联 T1 的哪一行与 T2 的哪一行...您应该将所有数据放在同一个表中,或者使用 DataRelation在两个表之间(但这需要额外的连接字段)。然后将 DataTable 设置为 ItemsSource,而不是 DataSet。

或者,您可以按照 Andy 的建议创建一个专用类来保存数据

【讨论】:

【参考方案3】:

WPF 绑定依赖于属性。例如,考虑以下Person 对象:

class Person

    public string FirstName  get; set; 
    public string LastName  get; set; 

然后,您可以通过执行以下操作修改 ListView 的 XAML 以显示 Person 对象的集合:

<ListView Margin="15,89,63,73" Name="lst" ItemsSource="Binding">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="First Name"
                DisplayMemberBinding="Binding Path=FirstName" />
            <GridViewColumn Header="Last Name"
                DisplayMemberBinding="Binding Path=LastName" />
        </GridView>
    </ListView.View>
</ListView>

这将在第一列中显示对象的名字,在第二列中显示他们的姓氏(假设ListViewDataContextPerson 对象的集合)。

理论上,要将DataTable 中的值绑定到ListView,您可以将ItemsSource 设置为DataTableRows 属性。问题在于DataRow 类没有公开其列的属性——只有Item 属性接受指定行的参数。据我所知,XAML 不支持带参数的属性,因此我认为不可能将DataTable 用作ItemsSourceListView

不过,您还有其他一些选择。您可以创建一个强类型的DataSet,这将公开一个DataTable,每个列都有一个属性。然后,您可以将每个 GridViewColumn 绑定到正确的属性。

另一种方法是根本不使用DataTable。您的数据层仍会将数据从您的源加载到DataTable,但随后会将这些数据转换为普通对象。您可以创建ObservableCollection 的实例,将每个对象添加到其中,然后将ListView 绑定到该实例。每个GridViewColumn 只会绑定到对象的相应属性。

更新:

回答 OP 的进一步问题:

我可以将 xsd 用于此目的吗?它 为每个数据表保存一个属性..

您需要的不仅仅是 DataTable 的属性。您还需要为 DataTable 的每一行中的每个值设置一个属性。否则 ListView 的列没有属性可以绑定。

【讨论】:

【参考方案4】:

这对我有用。

public partial class MainWindow : Window


   public  ObservableCollection<DataTable> _observableCollection =
   new ObservableCollection<DataTable>();

    public MainWindow()
    
        InitializeComponent();

        DataTable dt1 = new DataTable();
        dt1.Columns.Add("OrderID");
        dt1.Columns.Add("CustomerID");
        dt1.Columns.Add("ProductID");
        dt1.Rows.Add("test1", "test2", "test3");

        DataTable dt2 = new DataTable();
        dt2.Columns.Add("OrderID");
        dt2.Columns.Add("CustomerID");
        dt2.Columns.Add("ProductID");
        dt2.Rows.Add("test4", "test5", "test6");

        _observableCollection.Add(dtInformation1);
        _observableCollection.Add(dtInformation2);
    

    public ObservableCollection<DataTable> _Collection
        get  return _observableCollection;  

列表视图 XAML

<ListView  Height="Auto" 
HorizontalAlignment="Stretch" 
Name="somename" 
ItemsSource="Binding _Collection" VerticalAlignment="Stretch" Width="Auto" >

  <GridViewColumn  Header="OrderID" Width="auto" >
      <GridViewColumn.CellTemplate>
          <DataTemplate>
              <Button Tag="Binding OrderID" Content="Binding OrderID"/>
          </DataTemplate>
      </GridViewColumn.CellTemplate>
  </GridViewColumn>
  <GridViewColumn Width="auto" DisplayMemberBinding="Binding CustomerID" Header="CustomerID" />
  <GridViewColumn Width="auto" DisplayMemberBinding="Binding ProductID" Header="ProductID" />

【讨论】:

以上是关于将 wpf listview 绑定到数据集......可能......?的主要内容,如果未能解决你的问题,请参考以下文章

将 Web API 投影请求的结果绑定到 DataGrid 或 ListView 等 WPF 控件

WPF XAML - 将数据网格列绑定到外键(数据集)

如何将 Dictionary<enum, bool> 双向绑定到 WPF 中的 ListView 列?

在WPF中插入了一个ListView表格,在SQL中建了一个表,如何实现绑定?

WPF - 将 UserControl 可见性绑定到属性

如何将控件绑定到 WPF 列表视图列