将WPF ListView绑定到数据集(Dataset)......可行吗?

4
我很久以来一直在努力学习Wpf,但是在尝试将数据绑定到listview时卡住了。我想要将一个listview绑定到一个dataset(因为我想要在列中显示来自不同表的数据)。我附上了一个样例代码,它可以工作,但是listview只显示了一行。可能出了什么问题,请问有人能够指导我吗?所有可用的样例都使用了datatables,没有一个指定如何绑定到dataset。请帮帮我,任何建议都会非常感激。谢谢!
我的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;
4个回答

4

我完全同意Andy和Thomas的观点。他们都很优雅地解释了这个概念。

我只是展示了使用数据集执行相同操作的步骤。

这里不讨论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;
    }

在按钮的点击事件中,写入以下代码:
私有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... - Thomas Levesque
不小心发生了。我应该写成mydataset().Tables[0]。 - priyanka.sarkar
但是仍然没有办法将数据集绑定到列表视图或列表框中。我只想在列表框中显示来自多个数据表的数据。您可以将其绑定到对象。数据集和数据表都是对象。那么绑定到业务对象和数据集之间有什么区别呢? - biju

2
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 用作 ListViewItemsSource
但是,您还有其他选择。您可以创建一个强类型的 DataSet,它将公开每个列的属性的 DataTable。然后,您可以将每个 GridViewColumn 绑定到正确的属性。
另一种方法是根本不使用DataTable。您的数据层仍将从源加载数据到DataTable中,但然后会将该数据转换为普通对象。您可以创建一个ObservableCollection的实例,将每个对象添加到其中,然后将ListView绑定到它。每个GridViewColumn只需绑定到对象的相应属性即可。
更新:
针对OP的进一步问题的答案:
引用:
“我可以使用xsd来完成这个目的吗?它为每个datatable都保留了一个属性。”
您需要的不仅仅是DataTable的属性。您还需要每行中每个值的属性。否则,ListView的列没有属性可绑定。

2

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

abc1    xyz1
abc2    xyz2

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

另外,你也可以像Andy建议的那样创建一个专门的类来保存数据。


1

这对我有效。

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接