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
My 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>
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;
I'm not sure what you're trying to do here... Is that the result you expect ?
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.
Alternatively, you could create a dedicated class to hold the data, as suggested by Andy
This worked for me.
ListView XAML
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.
The MVVM (ModelView ViewModel) I am not discussing here.
The Xaml looks like this
In the .CS file create a dataset
Next in the Button's click event write the following
private void btnAddRecord_Click(object sender, RoutedEventArgs e)
N.B.~ You cannot assign the source of the ListView a dataset.
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.
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.
WPF Binding works off of properties. For example, consider the following
Person
object:You could then modify the XAML for your
ListView
to display a collection ofPerson
objects by doing the following: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 theListView
is a collection ofPerson
objects).In theory, to bind the values in a
DataTable
to aListView
, you could set theItemsSource
to theDataTable
'sRows
property. The problem becomes that theDataRow
class doesn't expose properties for its columns - there is only theItem
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 aDataTable
as theItemsSource
for aListView
.You do have some other options, however. You could create a strongly typed
DataSet
, which would expose aDataTable
with a property for each column. You can then bind eachGridViewColumn
to the correct property.Another approach would be to not use a
DataTable
at all. Your data layer would still load the data from your source into theDataTable
, 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 theListView
to that. EachGridViewColumn
would just bind to the corresponding property of the objects.Updated:
In answer to OP's further question:
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.