wpf 使用 C# 在每一行中动态地将按钮添加到 ListView

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19361940/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:50:50  来源:igfitidea点击:

Add Button to ListView dynamically in each row using C#

c#wpflistview

提问by Prateek Shukla

I have a ListViewin 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我必须显示从我的数据库表中提取的所有行。同样,我必须在每行中提供两个编辑和删除按钮。由于我是初学者,因此我在 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-

在 C# 中,我写道-

 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- enter image description here

我得到的结果是- 在此处输入图片说明

I want button over there, Please help me out.

我想要那边的按钮,请帮帮我。

回答by Omri Btian

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:

1) 你真的应该创建一个像@HighCore 建议的正确的数据类型。查看您的代码,我认为它看起来像这样:

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 ProductCategoryinstead of directly adding anonymous types

然后创建一个集合ProductCategory而不是直接添加匿名类型

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 ListViewwhich is wrong. What you should be doing is set your collection to be the ItemsSourceof your ListView.

2)您直接将项目添加到ListView错误的项目中。您应该做的是将您的收藏设置ItemsSource为您的ListView.

Tab1lstProductCategories.ItemsSource = list;

3) After using CellTemplateto achieve the ListViewwanted look through xaml and changing the DisplayMemberBindingbinding to the appropriate properties, you can bind the CommandParameterthrough the default {Binding}expression which will set the command parameter to be the ProductCategoryitem it represents.

3)使用通过xamlCellTemplate实现ListView想要的外观并将DisplayMemberBinding绑定更改为适当的属性后,您可以CommandParameter通过默认{Binding}表达式将命令参数设置为ProductCategory它所代表的项目。

    <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 - EditCategoryand DeleteCategory, you can extract the Id of the ProductCategory

从事件处理程序 -EditCategoryDeleteCategory,您可以提取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 MVVMpattern. this will mean not using event handlers in code behind but using Commandsinstead, and use CommandParameterthe way it was originally intended to be used.

一种。您应该高度考虑使用MVVM模式。这意味着不在代码中使用事件处理程序,而是使用命令,并使用CommandParameter它最初打算使用的方式。

b. Consider some ORMframework 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.

湾 考虑一些ORM框架,而不是将数据库直接绑定到您的 UI。这会产生令人难以置信的紧密耦合,这将使您的代码的可重用性和灵活性降低很多。

Hope this helps

希望这可以帮助