Добавьте строку после установки DataSource в Datagridview

У меня было много вопросов, связанных с привязкой datagrid к datasource. У меня был 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);

Но это невозможно, потому что Datasource из Datagrid привязывается к списку li. Итак, мой первый вопрос: как я могу это сделать?

Мой второй вопрос: Для этого я сделал решение изменить список List li и Add New, а затем установить его в datasource 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. Но почему это не работает при добавлении строки в datagrid?

Ответы

Ответ 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";

Также см. Реализация INotifyPropertyChanged - существует ли лучший способ?

Ответ 2

Вот решение для добавления строк в источник данных после привязки к DataGridView.

Обратите внимание, что я использовал пустую DataGridView "Mydgv" и кнопку "button1" в форме.

Также я использовал тот же "MyClass" из вашего вопроса.

Поместите одну кнопку с именем "button1" в форму и напишите этот код

    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 обновлен новой строкой.

Вместо того, чтобы устанавливать тот же объект List, что и DataSource, попробуйте список MyClass, как я заметил ниже.

Mydgv.DataSource = li.ToList <MyClass> ();

Чтобы было проще понять, я ставлю Id как случайное число от 10 до 100.

Надеюсь, вы проверите его и ответьте мне, если есть какие-либо проблемы с кодом.

Ответ 3

Следуйте за шагами.

  • Создайте свойство ObservableCollection MyClass.

    private ObservableCollection<MyClass> _li;
    
    public ObservableCollection<MyClass> Li
    {
        get; 
        set
        {
            _li = value;
            NotifyPropertyChangedEvent("Li");      
        }
    }
    
  • Привязать DataGrid DataSource к свойству "Li" в файле XAML.

  • Теперь, когда коллекция обновляется (например, элементы добавлены или удалены), DataSource автоматически обновится.

Ответ 4

создать глобальный

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

Внешняя сторона Page_load или любой функции

Добавьте/удалите любую строку из li внутри любой функции и вызовите строку ниже при изменении данных в li

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

Ответ 5

@Co. Aden

В соответствии с тем, что я вижу все, что вы делали в первой части привязки списка к сетке в качестве источника данных, отлично. Execpet, который вы пропустили, чтобы вызвать метод привязки данных после предоставления источника данных.

Как только вы вызываете метод DataBind, детали должны отображаться в сетке в соответствии с тем, что вы ожидали.

Mydgv.DataBind();

Пример ссылки:

С#:

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>