在c# win窗体中按下搜索按钮后编辑链接移位
本文关键字:按钮 编辑 链接 搜索 win 窗体 | 更新日期: 2023-09-27 18:03:06
我在网格视图中加载我的数据。在加载时,编辑链接位于网格视图的最右端,即网格视图的最后一列。
在这个网格视图中,我有多个字段输入的搜索功能。当我按搜索时,编辑链接显示为网格视图的第一列。
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
}
}
我找不到为什么会发生这种情况?请指导。
在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
条件中的代码。这应该可以解释你在另一个问题中所问的行为。
修复
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
,我们想要删除旧的