将 wpf 列表视图绑定到数据集......可能......?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/961877/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:32:23  来源:igfitidea点击:

Binding a wpf listview to a Dataset....Possible..?

wpfdata-bindingado.netbindingdataset

提问by

I was struggling moving to Wpf,I am just stuck while trying out databinding to a lsitview.I want to databind a listview to a dataset(dataset because the data i want to display in columns belongs to different tables).I am attaching a sample code that i am trying with.It works alright but the listliew only shows one row.What could be wrong.Can anyone guide me through.All the samples available are using datatables.None specifies about binding to a dataset.Pls help..any input will be highly appreciated...thanks in advance

我正在努力转移到 Wpf,我只是在尝试将数据绑定到 lsitview 时卡住了。我想将列表视图数据绑定到数据集(数据集,因为我想在列中显示的数据属于不同的表)。我正在附加一个示例我正在尝试的代码。它工作正常,但 listliew 只显示一行。可能有什么问题。任何人都可以指导我完成。所有可用的样本都使用数据表。没有指定关于绑定到数据集。请帮助..任何输入将受到高度赞赏...提前致谢

My Xaml

我的 Xml

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

My Code

我的代码

 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;

回答by priyanka.sarkar

Hi am in full accord with Andy and Thomas. They both have explained the concept elegantly.

嗨,完全符合安迪和托马斯的看法。他们都优雅地解释了这个概念。

I am only showing the steps of doing the same only with dataset.

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

The MVVM (ModelView ViewModel) I am not discussing here.

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

The Xaml looks like this

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>

In the .CS file create a dataset

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

Next in the Button's click event write the following

接下来在按钮的点击事件中写入以下内容

private void btnAddRecord_Click(object sender, RoutedEventArgs e)

私有无效 btnAddRecord_Click(对象发送者,RoutedEventArgs e)

    {

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

N.B.~ You cannot assign the source of the ListView a dataset.

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

Why ? You may ask? A dataset, in simple terms , is a collection of data tables.

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

Suppose you have 5 different datatables. And say none of their column names as well as column numbers are same.

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

Now you have assigned all those to your dataset. How will the controls source know that which source it has to bind?

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

Inorder to overcome such a situation, either make a custom datatable that will have all the columns of those discreet datatables and assign the values to this custom one and then bind to the source.

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

Or you need to explicitly specify the datatable in the datasource

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

But I always prefer to use MVVM pattern for this kind of operations.

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

回答by Andy

WPF Binding works off of properties. For example, consider the following Personobject:

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

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

You could then modify the XAML for your ListViewto display a collection of Personobjects by doing the following:

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

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

This will display the object's first name in the first column, and their last name in the second column (assuming that the DataContextof the ListViewis a collection of Personobjects).

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

In theory, to bind the values in a DataTableto a ListView, you could set the ItemsSourceto the DataTable's Rowsproperty. The problem becomes that the DataRowclass doesn't expose properties for its columns - there is only the Itemproperty that takes an argument specifying the row. To my knowledge, XAML does not support properties that take arguments, so I don't think that it is possible to use a DataTableas the ItemsSourcefor a ListView.

从理论上讲,在一个值绑定DataTableListView,你可以设置ItemsSourceDataTableRows财产。问题是DataRow该类不公开其列的Item属性- 只有带有指定行的参数的属性。据我所知,XAML 不支持带参数的属性,所以我认为不可能使用 aDataTable作为ItemsSourcefor a ListView

You do have some other options, however. You could create a strongly typed DataSet, which would expose a DataTablewith a property for each column. You can then bind each GridViewColumnto the correct property.

但是,您确实有其他一些选择。您可以创建一个强类型的DataSet,它将DataTable为每列公开一个具有属性的 。然后,您可以将每个绑定GridViewColumn到正确的属性。

Another approach would be to not use a DataTableat all. Your data layer would still load the data from your source into the DataTable, but it would then convert that data into normal objects. You could create an instance of ObservableCollection, add each of the objects into it, and then bind the ListViewto that. Each GridViewColumnwould just bind to the corresponding property of the objects.

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

Updated:

更新:

In answer to OP's further question:

回答 OP 的进一步问题:

Can I use the xsd for the purpose?.It holds a property for each datatable..

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

You need more than just a property for a DataTable. You'd also need a property for each value in each row of the DataTable. Otherwise there is no property for the ListView's columns to bind to.

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

回答by Thomas Levesque

I'm not sure what you're trying to do here... Is that the result you expect ?

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

abc1    xyz1
abc2    xyz2

There is no relation between your tables, so the binding system can't guess which row of T1 you want to associate with which row of T2... You should either put all data in the same table, or use a DataRelation between the two tables (but that would require extra fields for the join). You would then set the DataTable as the ItemsSource, not the DataSet.

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

Alternatively, you could create a dedicated class to hold the data, as suggested by Andy

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

回答by Christoffer

This worked for me.

这对我有用。

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

ListView XAML

列表视图 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" />