我有一个带有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
}
}
答案 0 :(得分:2)
您可以使用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);
}
}
答案 1 :(得分:2)
虽然Ivans解决方案100%有效且正确,但仍存在一些轻微的问题"抱怨"就美学而言(在他优雅的解决方案中,他可以很容易地满足)。如果您希望对话框直接显示在行的下方,请同时使用gridview的左侧和行底部,您需要采用不同的方式 - 很长的路要走。
我重申这一点 - 伊万斯解决方案非常合适且更加清洁。以下解决方案为您提供了更多关于表单放置等方面的自由。我几分钟就把它扔在一起,很抱歉,如果我错过了一些小事。
您始终可以使用内置属性,例如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);
}
现在大多数情况与伊万的情况大致相同,除了#34;更长的路线"但是这可以让您使用辅助函数更多地控制您的位置。您可以添加/删除调整值,并找到您喜欢的内容。工作正常。
希望这有帮助。
+1给Ivan以获得干净的解决方案。