在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       
    }
}

我找不到为什么会发生这种情况?请指导。

在c# win窗体中按下搜索按钮后编辑链接移位

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
    // ...
}

由于EditIndex可以变化,我们将通过Name来检查它。因为你是重新添加到DataGridView.Columns,我们想要删除旧的