我在网格视图中加载数据。在加载时,编辑链接位于网格视图的最右端,即网格视图的最后一列。
在此网格视图中,我具有使用多个字段输入进行搜索的功能。 当我按搜索时,编辑链接将显示为网格视图的第一列。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Library.UI
{
public partial class ReceiptReport : Form
{
private bool isSearchMode = false;
private bool isEditMode = false;
public ReceiptReport()
{
InitializeComponent();
isSearchMode = false;
GetReceipt(isSearchMode);
edit();
}
private void ReceiptReport_Load(object sender, EventArgs e)
{
dtpFrom.Value = DateTime.Today.AddDays(-1);
isEditMode = false;
FillPaymentMode();
this.WindowState = FormWindowState.Maximized;
}
private void edit()
{
DataGridViewLinkColumn Editlink = new DataGridViewLinkColumn();
Editlink.UseColumnTextForLinkValue = true;
Editlink.HeaderText = "Edit";
Editlink.DataPropertyName = "lnkColumn";
Editlink.LinkBehavior = LinkBehavior.SystemDefault;
Editlink.Text = "Edit";
receiptGrid.Columns.Add(Editlink);
}
private void receiptGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
int paymentTxnId_ = 0;
try
{
if (e.RowIndex >= 0 && receiptGrid.Columns[e.ColumnIndex].Index == 0)
{
DataRowView drv = receiptGrid.Rows[e.RowIndex].DataBoundItem as DataRowView;
paymentTxnId_ = Convert.ToInt32(drv.Row["paymentTxnId"]);
Receipt receiptFrm = new Receipt(paymentTxnId_);
receiptFrm.StartPosition = FormStartPosition.CenterParent;
receiptFrm.Show();
}
}
catch (Exception ex)
{
string title = "Error";
MessageBox.Show(ex.Message.ToString(), title);
}
}
private void GetReceipt(bool mode)
{
int dummyId = 0;
int getPaymentMode = 0;
string fromDate = string.Empty;
string toDate = string.Empty;
string payPartyName = string.Empty;
string recNum = string.Empty;
DataTable dt = new DataTable();
ReceiptDal objDal = new ReceiptDal();
try
{
if (mode == false)
{
dt = objDal.GetReceipt(dummyId);
receiptGrid.DataSource = dt;
receiptGrid.Columns[0].Visible = false;
}
else
{
receiptGrid.DataSource = null;
getPaymentMode = (int)cmbPaymentMode.SelectedValue;
fromDate = dtpFrom.Value.ToShortDateString();
toDate = dtpTo.Value.ToShortDateString();
payPartyName = txtPaymentPartyName.Text.Trim();
recNum = txtReceiptNum.Text.Trim();
dt = objDal.SearchReceipt(getPaymentMode, recNum, payPartyName, fromDate, toDate);
receiptGrid.DataSource = dt;
receiptGrid.Columns[0].Visible = false;
if (isEditMode == false)
{
edit();
isEditMode = true;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString(), "Error");
}
}
#region search
private void btnSearch_Click(object sender, EventArgs e)
{
try
{
ValidateDateTime(dtpFrom.Text, dtpTo.Text);
isSearchMode = true;
GetReceipt(isSearchMode);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString(), "Error");
}
}
#endregion
}
}
我找不到为什么会这样?请指导。
答案 0 :(得分:1)
在Form
构建期间,DataGridView
控件的许多方面都遵循不同的规则,而不是之后的规则。例如,数据绑定列与手动添加列的列索引。
为什么
以您的构造函数和一些模拟列为例:
public ReceiptReport() { InitializeComponent(); isSearchMode = false; GetReceipt(isSearchMode); // Adds N columns. ex. | Id | Name | Gender | edit(); // Adds link column. | Id | Name | Gender | Edit | }
运行GetReceipt
后,DataGridView
将有N列,暂时将0索引为N-1,隐藏第0列。运行edit
后,您的DataGridView
应该有N + 1列,但这里的内容会变得毛茸茸。按照添加的顺序,您可以直观地看到链接列为最后一列。但是,在构造函数完成运行之前,不会发生绑定。因此,即使您可以在视觉上看到像(例如)
/*Hidden*/
| Id | Name | Gender | Edit |
他们的列索引如下:
| 1 | 2 | 3 | 0 |
因此,CellContentClick
中你提出这个条件的原因是:
receiptGrid.Columns[e.ColumnIndex].Index == 0 // Trigger when link column's clicked.
但是,如果您要将相同的代码从构造函数移动到Form.Load
处理程序的开头,那么列仍然会在视觉上呈现相同的内容,但索引现在将如下所示:
| 0 | 1 | 2 | 4 |
如果出现混乱的默认行为,点击Search
会发生什么?调用GetReceipt
并运行以下代码:
receiptGrid.DataSource = null; // Remove bound columns. | Edit | // ... receiptGrid.DataSource = dt; // Re-add bound columns. | Edit | Id | Name | Gender | receiptGrid.Columns[0].Visible = false; /*Hide*/ if (isEditMode == false) { edit(); // Re-add edit column. | Edit | Id | Name | Gender | Edit | isEditMode = true; }
视觉上结果如下:
/*Hidden*/
| Edit | Id | Name | Gender | Edit |
因此,有2 Edit
列。第一个应该是隐藏的,虽然你的OP声明你看到它,所以我猜测还有一些额外的尝试并将代码转移到你的问题中。此外,可见Edit
列(非索引0)不会触发CellContentClick
条件内的代码。这应该可以解释您所询问的in your other question行为。
THE FIX
private void edit()
{
DataGridViewLinkColumn Editlink = new DataGridViewLinkColumn();
Editlink.Name = "Edit"; // ADD
// ...
}
private void GetReceipt(bool mode)
{
// ...
try
{
if (mode == false)
// ...
else
{
this.dataGridView1.DataSource = null;
this.dataGridView1.Columns.Clear(); // ADD
// ...
}
}
// ...
}
private void receiptGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
// ...
if (receiptGrid.Columns[e.ColumnIndex].Name == "Edit") // CHANGE
// ...
}
由于Edit
列Index
可能会有所不同,我们会通过Name
检查它。由于您要将其重新添加到DataGridView.Columns
,我们希望删除旧版本。