Tutorial :WPF Databinding: How can I bind a stored procedure to a Listview



Question:

I have a button that when clicked will run a stored procedure on a SQL Server and display the resulting data in a grid within the same window.

In windows forms world, I'd create a datatable, use a dataadapter to fill it and then assign the datatable to the DataSource propert of my DataGridView and poof... there's my data.

I'm tried something similar in WPF using a ListView with a Gridview and i cant seem to make it work. I have the following in my XAML:

<ListView Grid.Row="1" Name="Preview" ItemsSource="{Binding Path=Report}">    <GridView>      <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=FormalName}" />    </GridView>  </ListView>  

And in my C# code

private void CreateReport(object sender, RoutedEventArgs e)   {    DataTable dt = new DataTable("Report");    SqlConnection cn = new SqlConnection("Data Source=DailyTimesheets;               Initial Catalog=DailyTimesheets;Integrated Security=SSPI");      SqlCommand cm = new SqlCommand("Reports.PayrollHoursInterface", cn);    cm.Parameters.AddWithValue("@PayBatchID", 722);    cm.CommandType = CommandType.StoredProcedure;      SqlDataAdapter da = new SqlDataAdapter(cm);    da.Fill(dt);      Preview.DataContext=dt;  }  

When I clicka the button (that fires the CreateReport Method), my datatable gets filled and assigned to the Datacontext, but nothing displays.


Solution:1

I made a sample app and discovered you need to surround your GridView with ListView.View and set your ItemsSource to {Binding} just like the following:

<ListView Name="Preview" ItemsSource="{Binding}">  <ListView.View>    <GridView>      <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=FormalName}" />    </GridView>   </ListView.View>  </ListView>  


Solution:2

I think part of the problem is you are still thinking WinForms. Instead of binding a Grid to a Table, how about binding the ListBox to a Collection?

Try this instead:

1) Create another class that implements INotifyPropertyChanged. We are going to use this class for the DataContext. Think of it as your BindingEngine. I typically make this the DataContext of the Window itself, making it available anywhere in the Window.

2) Expose a property in the new class that is an ObservableCollection, where YourType is another class that implements INotifyPropertyChanged and exposes the data properties you wish to display.

3) Create a method in the Engine that populates your Collection. Then fire the PropertyChanged event when it is populated.

4) Bind the ListBox ItemsSource to the Property.

5) Create an ItemTemplate and use the property names from YourType for the Binding.

This is psuedo-code, but should get you close:

<Window>      <Window.Resources>          <ObjectDataProvider x:Key="MyEngineDS" ObjectType="{x:Type MyEngine:MyEngineNamespace}" d:IsDataSource="True"/>          <DataTemplate x:Key="ItemTemplate1">              <TextBlock Text="{Binding MyPropertyName}" />          </DataTemplate>      </Window.Resources>      <Window.DataContext>          <Binding Mode="OneWay" Source="{StaticResource MyEngineDS}"/>      </Window.DataContext>      <Grid x:Name="LayoutRoot">          <ListBox ItemsSource="MyCollection" ItemTemplate="{DynamicResource ItemTemplate1}" />      </Grid>  </Window>  

Hope this helps.


Solution:3

Try using ItemsSource="{Binding}" instead.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »