Добавьте строку после установки 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>