【问题标题】:Add a Row After Setting DataSource to Datagridview将 DataSource 设置为 Datagridview 后添加一行
【发布时间】:2013-12-24 17:00:15
【问题描述】:

我有很多与数据网格的数据源绑定相关的问题。我有一个 DatagridView,我从列表中设置 DataSource

List<Myclass> li = new List<MyClass>();

MyClass O = new MyClass();
O.Name = "Aden";
O.LastName = "B";
O.Id = 12;
li.Add(O);
O = new MyClass();
O.Name = "Li";
O.LastName = "S";
O.Id = 22;
li.Add(O);

Mydgv.DataSource = li;

MyClass 在哪里

public Class MyClass
{
 public string Name {get; set;}
 public string LastName {get; set;}
 public decimal Id {get; set;}
}

现在想向我的 DataGridView 添加一个新行

DataGridViewRow row = (DataGridViewRow)yourDataGridView.Rows[0].Clone();
row.Cells[0].Value = "XYZ";
row.Cells[1].Value = 50.2;
Mydgv.Rows.Add(row);

但不可能报错,因为Datagrid的Datasource与Listli绑定。 所以我的第一个问题是我怎么能做到这一点?

我的第二个问题是, 为此,我制定了一个解决方案来更改我的 List li 并向其添加新数据行,然后将其设置为 datagrid 的数据源,但我认为这不是一个可行的解决方案,还有更好的解决方案吗?

甚至尝试通过 CurrencyManager 来做到这一点

CurrencyManager currencyManager1 = (CurrencyManager)BindingContext[MyGrid.DataSource];
currencyManager1.SuspendBinding();
DataGridViewRow row = (DataGridViewRow)yourDataGridView.Rows[0].Clone();
row.Cells[0].Value = "XYZ";
row.Cells[1].Value = 50.2;
Mydgv.Rows.Add(row);
currencyManager1.ResumeBinding();

据我所知,我暂停了 DataGrid 的绑定以向 Grid 提供格式,正如我在我的一篇帖子 Make Row Visible false 中执行的那样。 但是为什么在这里向数据网格添加行不起作用?

【问题讨论】:

    标签: c# data-binding datagridview datasource currencymanager


    【解决方案1】:

    尝试使用 BindingList 而不是 List:

    BindingList<MyClass> li = new BindingList<MyClass>();
    

    然后您从列表本身添加或删除记录:

    li.Add(new MyClass() { Id = 15, LastName = "Z", Name = "Agent" });
    

    网格会自动显示新行。

    要让单个属性更新自动出现在网格中,那么您的类需要实现 INotifyPropertyChanged 接口:

    public class MyClass : INotifyPropertyChanged {
      public event PropertyChangedEventHandler PropertyChanged;
    
      protected void OnPropertyChanged(string propertyName) {
        if (PropertyChanged != null) {
          PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
      }
    

    然后您的财产将不得不引发事件:

    private string lastName = string.Empty;
    
    public string LastName {
      get { return lastName; }
      set {
        if (value != lastName) {
          lastName = value;
          OnPropertyChanged("LastName");
        }
      }
    }
    

    现在,如果您从代码更新一行,网格将显示该更新:

    li[1].LastName = "Q";
    

    另见Implementing INotifyPropertyChanged - does a better way exist?

    【讨论】:

      【解决方案2】:

      这里是数据源绑定DataGridView后向数据源添加行的解决方案。

      请注意,我在表单中使用了空白的 DataGridView“Mydgv”和按钮“button1”。

      我也使用了与您的问题相同的“MyClass”。

      在表单中放一个名为“button1”的Button并编写这段代码

          private void button1_Click(object sender, EventArgs e)
          {
              List<MyClass> li = (List<MyClass>)Mydgv.DataSource;
              MyClass O = new MyClass();
      
              O.Name = "XYZ";
              O.LastName = "G";
              O.Id = new Random().Next(10, 100);
              li.Add(O);
      
              Mydgv.DataSource = li.ToList<MyClass>();
          }
      

      单击按钮,您可以看到 DataGridView 已更新为新行。

      与其设置与 DataSource 相同的 List 对象,不如尝试下面提到的 MyClass 列表。

      Mydgv.DataSource = li.ToList();

      为了更容易理解,我将 ID 设置为 10 到 100 之间的随机数。

      如果代码有任何问题,希望您检查并回复我。

      【讨论】:

      • 我建议的解决方案是将新行添加到现有的绑定 DataGridView。如果您想解决与此相关的任何其他问题,请告诉我。我没有从你的问题中得到你的全部要求,除了我回答的那个。
      • 您所做的是通过更新列表从列表中更新 DataGridView,但我想通过手动将行添加到数据网格来更新我的 datgrid 而不是从更新列表中。
      • 这两种方式有什么区别。无论如何,即使在数据绑定完成之后,您也想向数据网格添加新行。一旦控件被数据绑定,您就无法更新其视图。为此,需要更改其源数据。
      • 是的,这是我的问题,我想手动更新我的视图以不更改其数据源.. 是否有任何方法可以暂停数据源的绑定
      • 但是如果没有数据源,您将如何在网格中显示值?
      【解决方案3】:

      按照这些步骤..

      1. 创建 MyClass 的 ObservableCollection 的属性。

        private ObservableCollection<MyClass> _li;
        
        public ObservableCollection<MyClass> Li
        {
            get; 
            set
            {
                _li = value;
                NotifyPropertyChangedEvent("Li");      
            }
        }
        
      2. 将 DataGrid 数据源绑定到 XAML 文件中的“Li”属性。

      3. 现在,每当更新集合(即添加或删除项目)时,DataSource 都会自动更新。

      【讨论】:

        【解决方案4】:

        创建全局

        List<Myclass> li = new List<MyClass>();
        

        Page_load 或任何函数的外部

        在任何函数内添加/删除任何行,并在更改 li 中的数据时调用以下行

        gridview.DataSource=li;
        gridview.DataBind();
        

        【讨论】:

          【解决方案5】:

          @Co.亚丁

          根据我所见,您在将列表绑定到网格作为数据源的第一部分中所做的一切都很好。提供数据源后错过调用databind方法的execpet。

          调用 DataBind 方法后,详细信息应按照您的预期显示在网格上。

          Mydgv.DataBind();
          

          参考样本:

          C#:

          public partial class home : System.Web.UI.Page
          {
              protected void Page_Load(object sender, EventArgs e)
              {
                  List<Student> students = new List<Student>();
                  for (int i = 0; i < 10; i++)
                  {
                      students.Add(new Student(){FirstName = "First Name - " +i.ToString(),LastName = "Last Name - "+i.ToString()});
                  }
                  students.Add(new Student() { FirstName = " ", LastName = " " });
                  UsingDataSourceAndDataBind(students);
          
              }
          
              private void UsingDataSourceAndDataBind(List<Student> students)
              {
                  GridView1.DataSource = students;
                  GridView1.DataBind();
              }
          }
          
          class Student
          {
              public string FirstName { get; set; }
              public string LastName { get; set; }
          }
          

          ASPX 代码:

          <body>
          <form id="form1" runat="server">
          <div>
              <asp:GridView ID="GridView1" runat="server">
              </asp:GridView>
          </div>
          </form>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-11-22
            • 2015-06-10
            • 1970-01-01
            • 2015-02-12
            • 2013-03-28
            • 1970-01-01
            • 1970-01-01
            • 2011-10-09
            相关资源
            最近更新 更多