如何转到datagridview中最后单击的行

本文关键字:单击 最后 何转 datagridview | 更新日期: 2023-09-27 18:11:32

以下代码用于填充DGV:

  private void frmSwitch_Load(object sender, EventArgs e)
    {
         // TODO: This line of code loads data into the 'newCityCollectionDataSet.PropertyInformation' table. You can move, or remove it, as needed.
        this.propertyInformationTableAdapter.Fill(this.newCityCollectionDataSet.PropertyInformation);
        // TODO: This line of code loads data into the 'newCityCollectionDataSet.ClientTable' table. You can move, or remove it, as needed.
        this.clientTableTableAdapter.Fill(this.newCityCollectionDataSet.ClientTable);
    }

这段代码允许我将必要的信息传递给"摘要表单":

    private void propertyInformationDataGridView_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
    {
        System.Data.DataRowView SelectedRowView;
        newCityCollectionDataSet.PropertyInformationRow SelectedRow;
        SelectedRowView = (System.Data.DataRowView)propertyInformationBindingSource.Current;
        SelectedRow = (newCityCollectionDataSet.PropertyInformationRow)SelectedRowView.Row;
        frmSummary SummaryForm = new frmSummary(this);
        SummaryForm.LoadCaseNumberKey(SelectedRow.CaseNumberKey, true, null);
        SummaryForm.LoadBRTNumberKey(SelectedRow.BRTNumber, null);
        SummaryForm.Show();
    }

我要做的是传递SelectedRow并添加1到下一行,如果当前SelectedRow不再有效(例如,当FileFinishedCheckBox在"摘要表单"上勾选时)。我也希望同样的事情发生在任何时候一个复选框在DataGridview上被选中,这样人们就不必滚动回他们正在处理的文件。

在需要时执行刷新的代码如下:

        public void PerformRefresh() 
        {
         this.propertyInformationBindingSource.EndEdit();
         this.propertyInformationTableAdapter.Fill(this.newCityCollectionDataSet.PropertyInformation);
         this.propertyInformationDataGridView.Refresh();      
        }

如何转到datagridview中最后单击的行

这个问题似乎分为两部分:

  1. 如何在两个windows窗体之间进行通信
  2. 如何更改datagridview中的选定行

有许多不同的方法来完成这两个任务,所以我只给你两种可行的方法。第一个(用于windows窗体)是最简单的,而第二个(用于更改选定的行)在我看来是正确的方法。

windows窗体之间的通信

在两个窗体之间进行通信的最直接的方法是将一个窗体的引用传递到另一个窗体。

假设你有一个打开Form1的Form2,你可以这样做:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        Form2 f = new Form2(this);
        f.Show();
    }
    public void ShowMessage(string message)
    {
        MessageBox.Show(message);
    }        
}
public partial class Form2 : Form
{
    private Form1 _parentForm;
    public Form2(Form1 parentForm)
    {
        InitializeComponent();
        _parentForm = parentForm;
        _parentForm.ShowMessage("I am a message from form1);
    }   
}

因此,在您的示例中,您将向父窗体添加一个方法,该方法将dgv3中选择的行的唯一值作为其参数,以显示在gdv1中。在该方法中(它是parentForm的成员,您将在下面显示居中代码)。

其他方法包括传递一个委托给子表单,这是使datagridview居中的方法。这样做的好处是,您不再被总是传入Form1所束缚,甚至可以针对复选框提供不同的操作,但实现起来会稍微复杂一些。

以DataGridView中选定记录为中心

我的首选方法是使用bindingsource为网格提供数据源。你也可以使用CurrentCell属性直接访问网格位置,但使用bindingsource,你会得到更多的bang for your buck。

在下面的代码中,我们有一个表单,它创建了一个BindingSource,将其数据源设置为MyBindingList类型的BindingList,然后将绑定源设置为datagridview的数据源。

BindingList中的对象有一个唯一的属性"PrimaryKey",允许我们找到它们。

然后显示居中代码,这实际上非常简单。

首先,我们通过调用绑定源的Find()方法获得所需您的绑定源中的索引。

第二,我们改变绑定源的位置(这也更新了datagridview的显示)。

最后,我们更改了datagridview的FirstDisplayedScrollingRowIndex,使所选行不在网格的顶部或底部(如果使用这一行,您将需要添加一个检查以确保这是一个有效的索引)。

public partial class Form1 : Form
{
    BindingSource bs;
    public Form1()
    {
        InitializeComponent();

        bs = new BindingSource();
        MyBindingList<BackingObject> backing_objects = new MyBindingList<BackingObject>();
        backing_objects.Add(new BackingObject{ PrimaryKey = 1, Name  = "Fred", Hidden = "Fred 1"});
        bs.DataSource = backing_objects;
        dataGridView1.DataSource = bs;
    }
    private void button1_Click(object sender, EventArgs e)
    {
        int index = bs.Find("PrimaryKey", 5);
        bs.Position = index;
        dataGridView1.FirstDisplayedScrollingRowIndex = index - 1;            
    }
}

最后要注意的是,开箱即用的bindinglist不支持bindingsource的Find()方法。这就是为什么我使用我的自定义MyBindingList。可以在这里找到实现此功能的代码。

本质上你需要一个像这样的类:

public class MyBindingList<T> : BindingList<T>
{
    protected override bool SupportsSearchingCore
    {
        get
        {
            return true;
        }
    }
    protected override int FindCore(PropertyDescriptor prop, object key)
    {
        // Get the property info for the specified property. 
        PropertyInfo propInfo = typeof(T).GetProperty(prop.Name);
        T item;
        if (key != null)
        {
            // Loop through the items to see if the key 
            // value matches the property value. 
            for (int i = 0; i < Count; ++i)
            {
                item = (T)Items[i];
                if (propInfo.GetValue(item, null).Equals(key))
                    return i;
            }
        }
        return -1;
    } 
}