【问题标题】:edit link shifted after pressing search button in grid view C# win form在网格视图 C# win 表单中按下搜索按钮后编辑链接移动
【发布时间】:2015-07-16 12:39:00
【问题描述】:

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

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

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# winforms datagridview


    【解决方案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 的行为。

    修复

    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,我们希望删除旧的。

    【讨论】:

    • 感谢您的清晰解释。我认为我这样做的方法是错误的。我试图在互联网上搜索相同但找不到​​示例。有没有其他方法可以正确处理同一件事。请提出建议。
    • 有没有其他办法?我肯定会说——这就是编程恕我直言的美妙之处。 正确?也许。但只有你知道你在这里想要完成的全部内容。据我所知,你正在做的事情应该可以很好地解决这些问题。它可能并不总是很漂亮,但有时这正是我们必须做的事情来克服 DataGridView 的一些奇怪行为。
    • 感谢您的帮助回复和 cmets。我真的很感谢你的帮助。谢谢!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多