将按钮列添加到 datagrid 视图导致问题

Posted

技术标签:

【中文标题】将按钮列添加到 datagrid 视图导致问题【英文标题】:adding button column to datagrid view causing problems 【发布时间】:2011-11-03 16:18:30 【问题描述】:

我有一个 datagridview 与来自数据库的数据绑定,工作正常。它在表单加载时加载数据。根据客户要求,我使用以下代码向数据网格视图添加了新按钮列

private void form1_load

           var productsbycount = abc.products.GroupBy(x => x.product_Id).Select(a => new
        
            productid = a.Key,
            prouctnam = a.FirstOrDefault().product_Name,
            productimage = a.FirstOrDefault().product_Image,
            productdescr = a.FirstOrDefault().product_Description,
            stockavailable = a.LongCount(),
            productprice = a.FirstOrDefault().product_Price
        );

        productbindingsource.DataSource = productsbycount;
        productgridview.DataSource = productbindingsource;
        DataGridViewButtonColumn buttoncolumn = new DataGridViewButtonColumn();
        productgridview.Columns.Add(buttoncolumn);
        buttoncolumn.Text = "Buy";
        buttoncolumn.HeaderText = "Buy";
        buttoncolumn.UseColumnTextForButtonValue = true;
        buttoncolumn.Name = "btnbuy";
        productgridview.Columns[0].Visible = false;


当表单加载正常时。

但我正在检查条件,例如,如果我们在列表视图中选择任何项目,则数据网格视图会根据所选项目进行排序......因为我已经这样做了......

if (lstviewcategories.SelectedItems[0].Value.ToString() == "All")

    var productsbycount = abc.products.GroupBy(x => x.product_Id).Select(a => new
      
          productid = a.Key,
          prouctnam = a.FirstOrDefault().product_Name,
          productimage = a.FirstOrDefault().product_Image,
          productdescr = a.FirstOrDefault().product_Description,
          stockavailable = a.LongCount(),
          productprice = a.FirstOrDefault().product_Price
       );

       productbindingsource.DataSource = productsbycount;
       productgridview.DataSource = productbindingsource;
       DataGridViewButtonColumn buttoncolumn = new DataGridViewButtonColumn();
       productgridview.Columns.Add(buttoncolumn);
       buttoncolumn.Text = "Buy";
       buttoncolumn.HeaderText = "Buy";
       buttoncolumn.UseColumnTextForButtonValue = true;
       buttoncolumn.Name = "btnbuy";
       productgridview.Columns[0].Visible = false;

如果我单击列表视图的第一项(“全部”),则数据网格视图为 工作正常.... 如果我再次单击 listview 第一项(“全部”),则按钮列是 出现两次.... 如果我再次单击 listview 第一项(“全部”),则按钮列是 出现了 3 次...

这是列表视图中所有项目发生的情况。

我的问题是,有没有其他方法可以将按钮列添加到数据网格视图?

我尝试在 form1.cs[design] 中添加按钮列,这将影响 datagridview 中的实际列。我正在使用 c# 语言在 winforms 中工作。任何人都可以对这些提出任何想法吗?

假设我在这个循环中删除下面的代码

if (lstviewcategories.SelectedItems[0].Value.ToString() == "All")


实际的按钮列消失了。有人可以帮忙吗?

修改代码:

第一个条件:如果 (lstviewcategories.SelectedItems[0].Text.ToString() == CategoryType.Type2)

                 var productsbycount = abc.products.GroupBy(x => x.product_Id).Where(a => a.FirstOrDefault().product_Price > 0 && a.FirstOrDefault().product_Price <= 1000)
                              .Select(a => new
                              
                                  productid = a.Key,
                                  prouctnam = a.FirstOrDefault().product_Name,
                                  productimage = a.FirstOrDefault().product_Image,
                                  productdescr = a.FirstOrDefault().product_Description,
                                  stockavailable = a.LongCount(),
                                  productprice = a.FirstOrDefault().product_Price
                             );
                 productbindingsource.ResetBindings(false);
                 /*productbindingsource.DataSource = productsbycount;
                 productgridview.DataSource = productbindingsource;
                 DataGridViewButtonColumn buttoncolumn = new DataGridViewButtonColumn();
                 productgridview.Columns.Add(buttoncolumn);
                 buttoncolumn.Text = "Buy";
                 buttoncolumn.HeaderText = "Buy";
                 buttoncolumn.UseColumnTextForButtonValue = true;
                 buttoncolumn.Name = "btnbuy";
                 productgridview.Columns[0].Visible = false;*/


             

第二个条件:

           if (lstviewcategories.SelectedItems[0].Text.ToString() == CategoryType.Type3)
             
                 var productsbycount = abc.products.GroupBy(x => x.product_Id).Where(a => a.FirstOrDefault().product_Price > 500 && a.FirstOrDefault().product_Price <= 1000)
                              .Select(a => new
                              
                                  productid = a.Key,
                                  prouctnam = a.FirstOrDefault().product_Name,
                                  productimage = a.FirstOrDefault().product_Image,
                                  productdescr = a.FirstOrDefault().product_Description,
                                  stockavailable = a.LongCount(),
                                  productprice = a.FirstOrDefault().product_Price
                              );
                 productbindingsource.ResetBindings(false);
              /* productbindingsource.DataSource = productsbycount;
                 productgridview.DataSource = productbindingsource;
                 DataGridViewButtonColumn buttoncolumn = new DataGridViewButtonColumn();
                 productgridview.Columns.Add(buttoncolumn);
                 buttoncolumn.Text = "Buy";
                 buttoncolumn.HeaderText = "Buy";
                 buttoncolumn.UseColumnTextForButtonValue = true;
                 buttoncolumn.Name = "btnbuy";
                 productgridview.Columns[0].Visible = false;*/

             

这两个条件不起作用..

【问题讨论】:

你是不是又复制了一遍代码?似乎是这样 - 您在上面的代码中添加了另一个按钮列... 我有一个按钮列的问题...... @ckoenig 你能解决我的问题吗.... 我们在这里提供帮助和建议,不要为您编写整个代码片段 =) CodeBlend 有一个观点 - 我认为 我们 现在正在解决一些“问题”的问题......据我所知,下面给出的答案就是你需要。我真的很想帮忙,但也许你应该尝试更多地了解这个主题。据我了解,您会将此代码出售给某些客户,我认为您和 ***s 的 Spaghetticode/blend 从长远来看不会对您有所帮助 【参考方案1】:

首先,我强烈建议您阅读 DRY 原则。要回答您的问题,我建议您使用 BindingSource 的刷新方法,以便您可以在不更改数据结构的情况下刷新 datagridview 中的数据。您应该只在加载时执行以下所有操作,然后在其他任何地方刷新数据,除非您真的想更改数据类型,例如数据来自不同的来源;

productbindingsource.DataSource = productsbycount;
        productgridview.DataSource = productbindingsource;
        DataGridViewButtonColumn buttoncolumn = new DataGridViewButtonColumn();
        productgridview.Columns.Add(buttoncolumn);
        buttoncolumn.Text = "Buy";
        buttoncolumn.HeaderText = "Buy";
        buttoncolumn.UseColumnTextForButtonValue = true;
        buttoncolumn.Name = "btnbuy";
        productgridview.Columns[0].Visible = false;

不要在下面的代码块中再次这样做,只需调用productbindingsource.ResetBindings(false)

if (lstviewcategories.SelectedItems[0].Value.ToString() == "All")
            
            

更新:另外,不要在此代码块中定义 var productsbycount,而是将其设置为最顶部的类变量,以便您可以在刷新数据时访问它的所有方法您将覆盖以前的 var productsbycount,它会非常有效。

UPDATE2: 'ResetBindings() 可以在您更改数据后的任何时候使用,但正如我已经说过的,您需要一个类级别的变量(AKA 将 var productsbycount 放在类),在这个例子中,它会在这个之后;

productprice = a.FirstOrDefault().product_Price
           );

UPDATE3:我再说一遍,我们是来帮助你的在这里,随着代码库的增长,这可能会给您带来极大的痛苦!;

namespace Test

    public partial class Form2 : Form
    
        BindingSource productbindingsource;
        var productsbycount;

        public Form2()
        
            InitializeComponent();
            Load += new EventHandler(Form2_Load);
        

        void Form2_Load(object sender, EventArgs e)
        
            productsbycount = abc.products.GroupBy(x => x.product_Id).Select(a => new
            
                productid = a.Key,
                prouctnam = a.FirstOrDefault().product_Name,
                productimage = a.FirstOrDefault().product_Image,
                productdescr = a.FirstOrDefault().product_Description,
                stockavailable = a.LongCount(),
                productprice = a.FirstOrDefault().product_Price
            );
            productbindingsource.DataSource = productsbycount;
            productgridview.DataSource = productbindingsource;
            DataGridViewButtonColumn buttoncolumn = new DataGridViewButtonColumn();
            productgridview.Columns.Add(buttoncolumn);
            buttoncolumn.Text = "Buy";
            buttoncolumn.HeaderText = "Buy";
            buttoncolumn.UseColumnTextForButtonValue = true;
            buttoncolumn.Name = "btnbuy";
            productgridview.Columns[0].Visible = false;
        

        private void methodNameHere()
        
            productsbycount = abc.products.GroupBy(x => x.product_Id).Where(a => a.FirstOrDefault().product_Price > 0 && a.FirstOrDefault().product_Price <= 1000)
                              .Select(a => new
                              
                                  productid = a.Key,
                                  prouctnam = a.FirstOrDefault().product_Name,
                                  productimage = a.FirstOrDefault().product_Image,
                                  productdescr = a.FirstOrDefault().product_Description,
                                  stockavailable = a.LongCount(),
                                  productprice = a.FirstOrDefault().product_Price
                              );

            productbindingsource.ResetBindings(false);
        
    

【讨论】:

请重新措辞/扩展问题,我不确定您的意思 ResetBindings() 方法 - Causes a control bound to the BindingSource to reread all the items in the list and refresh their displayed values. 这对你的问题有帮助吗,你能关注一下吗? 您已将 ResetBindings() 放在正确的位置,但为了使其正常工作,您需要将变量创建移动到类的顶部(以便所有方法都可以访问它)然后只需在您的 if 语句中设置它而不使用 var,如下所示: productsbycount = tgs.products.GroupBy(x => x.product_Id).Where(a => a.FirstOrDefault().product_Price > 500 && a.FirstOrDefault() .product_Price @user899271 让我们continue this discussion in chat【参考方案2】:

非常感谢您的支持,我已经解决了我的问题......像这样......在表单加载时,我已将按钮列添加到数据网格视图......当我检查条件时下面这个..

if (lstviewcategories.SelectedItems[0].Text.ToString() == CategoryType.Type2)

我刚刚分配如下......

productgridview.datasource = productsbycount.Where(a => a.FirstOrDefault().product_Price > 0 && a.FirstOrDefault().product_Price <= 1000)  

幸运的是它运行良好.......

【讨论】:

以上是关于将按钮列添加到 datagrid 视图导致问题的主要内容,如果未能解决你的问题,请参考以下文章

将数据添加到 DataGrid 中的特定列

easyUI——页面多个datagrid导致表头与数据错位

在运行时将新表重新加载/替换到 WPF DataGrid 中

easyUI的datagrid每行数据添加操作按钮的方法

DataGrid 创建 RadioButton 列

以编程方式将新行添加到数据网格视图