在网格视图C#win form中按搜索按钮后,编辑链接被移动

时间:2015-07-16 12:39:00

标签: c# winforms datagridview

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

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

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

我找不到为什么会这样?请指导。

1 个答案:

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

由于EditIndex可能会有所不同,我们会通过Name检查它。由于您要将其重新添加到DataGridView.Columns,我们希望删除旧版本。