如何转到数据网格视图中的最后一次单击行

时间:2011-10-18 19:27:56

标签: c# winforms datagridview

以下代码用于填充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();      
        }

任何帮助都会很棒。

1 个答案:

答案 0 :(得分:2)

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

  1. 如何在两个窗体之间进行通信
  2. 如何更改datagridview中的选定行
  3. 很多不同的方法可以实现这两项任务,所以我只想给你两个可行的方法。第一个(对于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可以获得更多优势。

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

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

    然后我会显示实际上非常简单的居中代码。

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

    其次,我们更改绑定源位置(这也会更新datagridview显示)。

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

    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的原因。可以找到实现此目的的代码here

    基本上你需要一个类如下的类:

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