在网格视图C#win窗体中按下搜索按钮后,编辑链接移动 [英] edit link shifted after pressing search button in grid view C# win form

查看:158
本文介绍了在网格视图C#win窗体中按下搜索按钮后,编辑链接移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在网格视图中加载了我的数据。在加载时,编辑链接位于网格视图的最右端,即网格视图的最后一列。



在此网格视图中,我具有搜索多个字段输入的功能。
当我按搜索时,编辑链接将显示为网格视图的第一列。

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆