Winforms - 将新表单直接放置在父项的 Datagridview 选定行下

本文关键字:Datagridview 新表单 表单 Winforms | 更新日期: 2023-09-27 18:36:32

我有一个带有DataGridView的表单。我选择一行(始终是单行)数据。单击按钮后,我想打开一个新表单,并始终将其直接放置在所选行下方。我应该怎么做?

在我的按钮单击中,我做了这样的事情:

private void myBtn_Click(object sender, EventArgs e)
    {
        if (myDGV.SelectedCells.Count > 0)
        {
            int i = myDGV.SelectedCells[0].RowIndex;
            DataGridViewRow r = myDGV.Rows[i];
            // READ SOME DATA FROM THE ROW
            newForm form = new newForm();
            //POPULATE THE NEW FORM WITH DATA
            form.ShowDialog(this); //POSITION OF THIS FORM SHOULD BE DIRECTLY UNDER SELECTED ROW
        }
    }

Winforms - 将新表单直接放置在父项的 Datagridview 选定行下

可以使用

DataGridView.GetRowDisplayRectangle 获取数据网格视图客户端坐标中的行矩形,然后使用 Control.RectangleToScreen 将它们转换为确定新窗体位置所需的屏幕坐标,如下所示:

private void myBtn_Click(object sender, EventArgs e)
{
    if (myDGV.SelectedCells.Count > 0)
    {
        int i = myDGV.SelectedCells[0].RowIndex;
        DataGridViewRow r = myDGV.Rows[i];
        // READ SOME DATA FROM THE ROW
        newForm form = new newForm();
        //POPULATE THE NEW FORM WITH DATA ...
        // Position the form under the selected row
        form.StartPosition = FormStartPosition.Manual;
        var rect = myDGV.RectangleToScreen(myDGV.GetRowDisplayRectangle(i, false));
        form.Location = new Point(rect.Left, rect.Bottom);
        form.ShowDialog(this);
    }
}

虽然 Ivans 的解决方案是 100% 有效和正确的,但就美学而言,它有一些小的"抱怨"(他可以很容易地在他的优雅解决方案中迎合)。如果您希望对话框直接显示在行下方,与网格视图的左侧和行底部齐平,则需要以不同的方式执行此操作 - 漫长的路。

我重申这一点 - Ivans 的解决方案非常合适且更干净。下面的解决方案为您提供了有关表单放置等方面的更多自由。我在几分钟内把它放在一起,如果我错过了一些小东西,我很抱歉。

您始终可以使用内置属性,如Rectangle.Bottom等。我这样做是为了,我想,展示如何处理事情的数学。

private void myBtn_Click(object sender, EventArgs e)
{    
    if(dataGridView1.SelectedRows.Count > 0)
    {
        var rowIndex = myDGV.SelectedRows[0].Index;
        var row = myDGV.Rows[rowIndex];
        var formLocation = this.Location; //Form location
        var gridLocation = myDGV.Location; //grid location
        var rowLocation  = myDGV.GetRowDisplayRectangle(rowIndex, false).Location; //row location
        newForm form = new newForm();
        form.StartPosition     = FormStartPosition.Manual; //set to manual
        //form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
        //form.BackColor       = Color.Blue;
        form.Location = GetPopupStartingLocation(
            new Point[] 
                { 
                    formLocation, 
                    gridLocation, 
                    rowLocation 
                }, 
            row.Height);
        form.Show(this);
    }
}
/*
A small helper method - didn't need to put this in a method
but I did it for clarity.
*/
 private Point GetPopupStartingLocation(Point[] locations, int rowHeight)
 {
    var yPadding = 5;
    var xValues  = locations.Sum(x => x.X);
    var yValues  = locations.Sum(x => x.Y) + ((rowHeight * 2) + yPadding);
    return new Point(xValues, yValues);
 }

现在,除了"更长的路线"之外,大部分内容都与Ivan的几乎相同,但这使您可以使用辅助功能对位置进行更多控制。您可以添加/删除调整值并找到您喜欢的内容。工作正常。

希望这有帮助。

+1 给伊万干净的解决方案。