在网格视图C#win窗体中按下搜索按钮后,编辑链接移动 [英] edit link shifted after pressing search button in grid view C# win form
问题描述
在此网格视图中,我具有搜索多个字段输入的功能。
当我按搜索时,编辑链接将显示为网格视图的第一列。
using System;
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data;
使用System.Drawing;
使用System.Linq;
使用System.Text;
使用System.Threading.Tasks;
使用System.Windows.Forms;
命名空间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 =编辑;
Editlink.DataPropertyName =lnkColumn;
Editlink.LinkBehavior = LinkBehavior.SystemDefault;
Editlink.Text =编辑;
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作为DataRowView;
paymentTxnId_ = Convert.ToInt32(drv.Row [paymentTxnId]);
收据收据Frm =新收据(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;
从Date = 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
}
}
我找不到为什么会发生这种情况?请指导。
在表单
中, DataGridView
通过一组不同于之前的规则控制播放。例如,数据绑定列与手动添加列的列索引。
为什么
例如,您的构造函数和一些嘲弄的列:
public ReceiptReport()
{
InitializeComponent();
isSearchMode = false;
GetReceipt(isSearchMode); //添加N列。例如| Id |名称|性别|
edit(); //添加链接列。 | Id |名称|性别|编辑|
}
之后 GetReceipt
运行, DataGridView
将具有N列,临时索引为0到N-1,列0隐藏。运行编辑
后,您的 DataGridView
应该有N + 1列,但这里的东西会变得毛茸茸。按照添加的顺序,您可以直观地看到链接列为最后一个。但是,直到构造函数完成运行才会发生绑定。因此,即使您可以在视觉上看到列出的列(例如):
/ *隐藏* /
| Id |名称|性别|编辑|
他们的列索引如下:
| 1 | 2 | 3 | 0 |
因此,在 CellContentClick
中的原因做了这个条件:
receiptGrid.Columns [e.ColumnIndex] .Index == 0 //当链接列被点击时触发。
但是,如果要从构造函数中移动相同的代码进入您的 Form.Load
处理程序的开头,列仍然可视化呈现相同的,但索引现在将如下所示:
| 0 | 1 | 2 | 4 |
如果您点击搜索
? GetReceipt
被调用,并运行以下代码:
receiptGrid.DataSource = null; //删除绑定列。 |编辑|
// ...
receiptGrid.DataSource = dt; //重新添加绑定列。 |编辑| Id |名称|性别|
receiptGrid.Columns [0] .Visible = false; / *隐藏* /
如果(isEditMode == false)
{
edit(); //重新添加编辑列。 |编辑| Id |名称|性别|编辑|
isEditMode = true;
}
视觉上这个结果如下: p>
/ *隐藏* /
|编辑| Id |名称|性别|编辑|
因此,有2个编辑
列。第一个应该是隐藏的,虽然你的OP表示你看到它,所以我猜测还有一些额外的尝试,并将代码传递到你的问题。另外,可见的编辑
列(NOT索引0)不会触发 CellContentClick
条件中的代码。这应该解释您在您的其他问题中提出的行为。
THE FIX
private void edit()
{
DataGridViewLinkColumn Editlink = new DataGridViewLinkColumn();
Editlink.Name =编辑; // ADD
// ...
}
private void GetReceipt(bool mode)
{
// ...
try
{
if(mode == false)
// ...
else
{
this.dataGridView1.DataSource =空值;
this.dataGridView1.Columns.Clear(); // ADD
// ...
}
}
// ...
}
private void receiptGrid_CellContentClick(object sender ,DataGridViewCellEventArgs e)
{
// ...
if(receiptGrid.Columns [e.ColumnIndex] .Name ==Edit)// CHANGE
//。 ..
}
由于编辑
列索引
可能有所不同,我们会通过 Name
来检查它。而且由于您将其重新添加到 DataGridView.Columns
中,我们要删除旧的。
I load my data in grid view. At loading time, the edit link is at the right most end of the grid view i.e. the last column of the grid view.
In this grid view, I've feature of searching with multiple fields input. When I press search the edit link appears as the first column of the grid view.
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
}
}
I can not find why is this happening? Please guide.
During Form
construction, many aspects of a DataGridView
control play by a different set of rules than they do afterwards. For example, the column indexing for data bound columns versus manually added columns.
THE WHY
Take, for example, your constructor and some mocked columns:
public ReceiptReport() { InitializeComponent(); isSearchMode = false; GetReceipt(isSearchMode); // Adds N columns. ex. | Id | Name | Gender | edit(); // Adds link column. | Id | Name | Gender | Edit | }
After GetReceipt
is run, the DataGridView
will have N columns, temporarily indexed 0 to N-1, with column 0 hidden. After edit
is run, your DataGridView
should have N+1 columns, but here's where things get hairy. By the order they were added, you'll visually see the link column as the last. However, bindings don't occur until the constructor has finished running. Therefore, even though you may visually see the columns ordered like (ex.):
/*Hidden*/
| Id | Name | Gender | Edit |
Their column index is as follows:
| 1 | 2 | 3 | 0 |
Hence, the reason in CellContentClick
that you made this condition:
receiptGrid.Columns[e.ColumnIndex].Index == 0 // Trigger when link column's clicked.
However, if you were to move that same code from the constructor into the beginning of your Form.Load
handler, the columns would still visually render the same but the indexing would now be as follows:
| 0 | 1 | 2 | 4 |
With that messy default behavior in place, what happens when you click Search
? GetReceipt
is called and the following code runs:
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; }
Visually this results as follows:
/*Hidden*/
| Edit | Id | Name | Gender | Edit |
Consequently, there are 2 Edit
columns. The first one should be hidden, although your OP states that you see it, so I'm guessing there's some additional attempts and carry over of code into your question. Additionally, the visible Edit
column (NOT index 0) will not trigger the code within the CellContentClick
condition. This should explain the behavior your were asking about 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
// ...
}
Since the Edit
column Index
can vary, we'll check for it by Name
instead. And since you are re-adding it to DataGridView.Columns
, we want to remove the old one.
这篇关于在网格视图C#win窗体中按下搜索按钮后,编辑链接移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!