将 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
Binding a wpf listview to a Dataset....Possible..?
提问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 Person
object:
WPF 绑定适用于属性。例如,考虑以下Person
对象:
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
You could then modify the XAML for your ListView
to display a collection of Person
objects 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 DataContext
of the ListView
is a collection of Person
objects).
这将在第一列中显示对象的名字,在第二列中显示他们的姓(假设DataContext
的ListView
是Person
对象的集合)。
In theory, to bind the values in a DataTable
to a ListView
, you could set the ItemsSource
to the DataTable
's Rows
property. The problem becomes that the DataRow
class doesn't expose properties for its columns - there is only the Item
property 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 DataTable
as the ItemsSource
for a ListView
.
从理论上讲,在一个值绑定DataTable
到ListView
,你可以设置ItemsSource
到DataTable
的Rows
财产。问题是DataRow
该类不公开其列的Item
属性- 只有带有指定行的参数的属性。据我所知,XAML 不支持带参数的属性,所以我认为不可能使用 aDataTable
作为ItemsSource
for a ListView
。
You do have some other options, however. You could create a strongly typed DataSet
, which would expose a DataTable
with a property for each column. You can then bind each GridViewColumn
to the correct property.
但是,您确实有其他一些选择。您可以创建一个强类型的DataSet
,它将DataTable
为每列公开一个具有属性的 。然后,您可以将每个绑定GridViewColumn
到正确的属性。
Another approach would be to not use a DataTable
at 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 ListView
to that. Each GridViewColumn
would 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" />