I have a ListView
in which I have to show all rows fetched from my database table. Again I have to give two edit and delete buttons in each row. As I am beginner for the same, I tried the following code in XAML-
<ListView Height="352" HorizontalAlignment="Left" Margin="20,90,0,0" Name="Tab1lstProductCategories" VerticalAlignment="Top" Width="1008">
<ListView.View>
<GridView>
<GridViewColumn Header="Category Name" DisplayMemberBinding="{Binding Col1}" Width="200"/>
<GridViewColumn Header="Created Date" DisplayMemberBinding="{Binding Col2}" Width="200"/>
<GridViewColumn Header="Last Updated" DisplayMemberBinding="{Binding Col3}" Width="200"/>
<GridViewColumn Header="Edit" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Edit" Click="EditCategory" CommandParameter="{Binding Id}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Delete" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Delete" Click="DeleteCategory"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
And in C# I Wrote-
DataTable dt=db.Select("select * from ProductCategories");
for (int i = 0; i < dt.Rows.Count; i++)
{
//Button edit, delete;
//edit = new Button();
//edit.Content="Edit";
//edit.Click += EditCategory;
//delete= new Button();
//delete.Content="Delete";
//delete.Click += DeleteCategory;
//edit.CommandParameter = dt.Rows[i]["Id"];
//delete.CommandParameter = dt.Rows[i]["Id"];
Tab1lstProductCategories.Items.Add(new { Col1 = dt.Rows[i]["CategoryName"], Col2 = dt.Rows[i]["CreatedDate"], Col3=dt.Rows[i]["LastUpdated"]});
}
private void EditCategory(object sender, RoutedEventArgs e)
{
Button b=sender as Button;
MessageBox.Show(b.CommandParameter.ToString());
}
private void DeleteCategory(object sender, RoutedEventArgs e)
{
}
I got the result as-
I want button over there, Please help me out.
Ok, so I see a couple of issues with your code.
1) You really should create a proper datatype like @HighCore suggested. Looking at your code I assume it will look something like this:
public class ProductCategory
{
public int Id { get; set; }
public string CategoryName { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime LastUpdated { get; set; }
}
Then create a collection of ProductCategory
instead of directly adding anonymous types
DataTable dt=db.Select("select * from ProductCategories");
// Create a collection for your types
ObservableCollection<ProductCategory> list = new ObservableCollection<ProductCategory>();
for (int i = 0; i < dt.Rows.Count; i++)
{
ProductCategory productCategory = new ProductCategory
{
// Casting might be needed here depending on your data types ...
Id = dt.Rows[i]["Id"],
CategoryName = dt.Rows[i]["CategoryName"],
CreatedDate = dt.Rows[i]["CreatedDate"],
LastUpdated = dt.Rows[i]["LastUpdated"]
};
list.Add(productCategory);
}
2) You are directly adding item's to the ListView
which is wrong. What you should be doing is set your collection to be the ItemsSource
of your ListView
.
Tab1lstProductCategories.ItemsSource = list;
3) After using CellTemplate
to achieve the ListView
wanted look through xaml and changing the DisplayMemberBinding
binding to the appropriate properties, you can bind the CommandParameter
through the default {Binding}
expression which will set the command parameter to be the ProductCategory
item it represents.
<ListView Height="352" HorizontalAlignment="Left" Margin="20,90,0,0" Name="Tab1lstProductCategories" VerticalAlignment="Top" Width="1008">
<ListView.View>
<GridView>
<GridViewColumn Header="Category Name" DisplayMemberBinding="{Binding CategoryName}" Width="200"/>
<GridViewColumn Header="Created Date" DisplayMemberBinding="{Binding CreatedDate}" Width="200"/>
<GridViewColumn Header="Last Updated" DisplayMemberBinding="{Binding LastUpdated}" Width="200"/>
<GridViewColumn Header="Edit" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Edit" Click="EditCategory" CommandParameter="{Binding}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Delete" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Delete" Click="DeleteCategory" CommandParameter="{Binding}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
From the event handlers - EditCategory
and DeleteCategory
, you can extract the Id of the ProductCategory
private void EditCategory(object sender, RoutedEventArgs e)
{
Button b=sender as Button;
ProductCategory productCategory = b.CommandParameter as ProductCategory;
MessageBox.Show(productCategory.Id);
}
This should be sufficient to make your code work, but there are several other points I'd like to make
a. You should highly consider using MVVM pattern. this will mean not using event handlers in code behind but using Commands instead, and use CommandParameter
the way it was originally intended to be used.
b. Consider some ORM framework instead of binding the database directly to your UI. this create incredibly tight coupling which will make your code a lot less reusable, and flexible.
Hope this helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With