[英]datagridview.Columns[""].Index doesn't work after setting new datasource
我以编程方式向我的 datagridview 添加了一个删除按钮列,它工作正常。 但是,当我将 datagridview 设置为新的数据源时,CellClick function 在打印出 0 而不是正确值的 6 时不再起作用。
//prints out 6
private void DataGridView_PromoList_CellClick(object sender, DataGridViewCellEventArgs e)
{
Console.WriteLine(DataGridView_PromoList.Columns["dataGridViewDeleteButton"].Index);
}
// above function prints out 0 after this functions called
private void cmbbxFilter_SelectedIndexChanged(object sender, EventArgs e)
{
//probably don't need this try catch because not reloading database
try {
int index = cmbbxFilter.SelectedIndex;
// Only do something if selecting different index in filter
if (lastFilterIndex != index)
{
lastFilterIndex = index;
etp.loadDisplayDT(index);
DataGridView_PromoList.DataSource = etp.displayDT;
Console.WriteLine("REFRESHED!");
}
}
catch (Exception ex)
{
showAlertUser("ERROR: " + ex.Message.ToString(), false);
//.Windows.Forms.Application.Exit();
}
}
我不确定在每一行添加一个删除按钮是否明智。 考虑在“删除”列中为每一行提供一个复选框,以及一个Save
按钮(或确定,立即应用)以启动所有选中项目的删除操作。
将此界面与编辑文本文件进行比较:只要操作员没有选择Save
,他就可以进行更改。 如果他不想使更改生效,请不要按确定。
因此,如果操作员犯了错误,该项目不会立即删除。 他可以撤消点击。
为此,您需要将 DataGridviewButtonColumn 更改为DataGridViewCheckBoxColumn 。
如果要显示Customers
序列,则必须创建一个 class DisplayedCustomers
,它聚合Customers
并有一个额外的列IsDeleted
:
class Customer {...}
class DisplayedCustomer
{
public Customer Customer {get; set;}
// Do readonly like this:
public int Id => this.Customer.Id;
// changeable properties like this:
public string Name
{
get => this.Customer.Name;
set => this.Customer.Name = value;
}
... // other properties
// Add: IsDeleted
public bool IsDeleted {get; set;}
}
您已经在使用 DataSource 来显示您的客户(或您显示的任何内容)。 使用 Visual Studio Designer 或手动将代码更改为类似于以下内容:
public MyForm()
{
InitializeComponents();
this.columnId.DataPropertyName = nameof(DisplayedCustomer.Id);
this.columnName.DataProperyName = nameof(DisplayedCustomer.Name);
...
this.columnIsDeleted.DataPropertyName = nameof(DisplayedCustomer.IsDeleted);
}
public BindingList<DisplayedCustomer> DisplayedCustomers()
{
get => (BindingList<DisplayedCustomer>)this.dataGridView1.DataSource;
set => this.dataGridView1.DataSource = value;
}
public void InitCustomerDisplay()
{
IEnumerable<Customer> customers = this.FetchCustomersToDisplay(...);
IEnumerable<DisplayedCustomer> customersToDisplay = customers
.Select(customer => new DisplayedCustomer {Customer = customer});
this.DisplayedCustomers = new BindingList<DisplayedCustomer>(
customersToDisplay.ToList());
}
显示所有客户,有一个额外的列 IsDeleted。 操作员所做的任何更改都会在客户中自动更新,属性 IsDeleted 除外。
当操作员单击Ok
或Apply Now
时删除客户:
private void OnButtonApplyNow_Clicked(object sender, ...)
{
IEnumerable<Customer> customersToDelete = this.DisplayedCustomers
.Where(displayedCustomer => displayedCustomer.IsDeleted)
.Select(displayedCustomer => displayedCustomer.Customer);
this.DeleteCustomers(customersToDelete);
}
考虑将 IsDeleted 作为列添加到数据库表中。 调整您的存储库,以便对于大多数用户而言,它仅获取未删除的客户。
更改存储库属性:
public IQueryable<Customer> Customers => dbContext.Customers;
进入:
public IQueryable<Customer> Customers => dbContext.Customers
.Where(customer => !customer.IsDeleted);
这样,每当有人不小心删除了一个项目时,它并没有真正删除,他可以给超级用户发送电子邮件并要求取消删除该项目。 当然,超级用户与数据库的接口略有不同。
定期,例如每月一次,将启动一个额外的过程来删除所有之前删除的项目。 为此,最好有一个可为空的 DeleteDate 列:如果 null,则不是 IsDeleted,如果不是 null,则额外进程可以使用该值仅删除半年前删除的项目。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.