C# Winforms 麻烦将窗体置于控件的中心,可以将其置于其他控件的中心
C# Winforms trouble centering a form over a control, can center it over other controls
我有一个在多个页面上有多个控件的应用程序。我正在使用 Telerik Winforms 控件。其中一个页面在 UserControl
中有一个 RadGridView
,它在 RadPageView
中的 RadPageViewPage
上,而后者又嵌套在另一个 RadPageViewPage
中RadPageView
。下面的代码基本上只是处理一个装在它自己的透明窗体中的加载微调器。当然,它总是在自己的线程上调用。
private static void RunWaiting(Control c, string text)
{
wf = new WaitingForm();
wf.drwbieSpinnerFrame.Text = text;
wf.ShowInTaskbar = false;
wf.Left = c.Left + (c.Width / 2);
wf.Top = c.Top + (c.Height / 2);
wf.Width = c.Width;
wf.Height = c.Height;
wf.FormBorderStyle = FormBorderStyle.None;
wf.ControlBox = false;
wf.TopMost = true;
wf.StartPosition = FormStartPosition.Manual;
Application.Run(wf);
}
显然,我希望微调器 (WaitForm
) 按需显示在控件的中心。如果我将容纳 RadGridView
的主 UserControl
传递给它,我也可以将它传递给该控件的父控件并以 RadPageViewPage
为中心。如果我将此方法传递给 RadGridView
,微调器根本不会出现,即使调用了代码并且仍然设置了“wf
”的属性。谁能告诉我我错过了什么?
不幸的是,耗时的任务本身正在更新 UI 并且由于其他原因必须存在于 UI 线程上,但我能够通过使用递归 class 这让我得到了适当的 (x,y) 坐标来在控件中间显示一个表单。
private static void RunWaiting(Control c, string text)
{
wf = new WaitingForm();
wf.drwbieSpinnerFrame.Text = text;
wf.ShowInTaskbar = false;
int[] tl = GetTopLefts(c);
wf.Top = (tl[0] + (c.Height / 2)) - (wf.Height / 2);
wf.Left = (tl[1] + (c.Width / 2)) - (wf.Width / 2);
wf.FormBorderStyle = FormBorderStyle.None;
wf.ControlBox = false;
wf.TopMost = true;
wf.StartPosition = FormStartPosition.Manual;
IsHolding = true;
Application.Run(wf);
}
以及获取位置数据调用的方法:
private static int[] GetTopLefts(Control c)
{
int top, left;
top = c.Top;
left = c.Left;
if (c.Parent != null)
{
int[] parentPoint = GetTopLefts(c.Parent);
top += parentPoint[0];
left += parentPoint[1];
}
return new int[] { top, left };
}
您可以通过将 GetTopLefts()
的最终输出设为 Point
来很好地解决这个问题,但这种方式的某些方面感觉更可靠。
我有一个在多个页面上有多个控件的应用程序。我正在使用 Telerik Winforms 控件。其中一个页面在 UserControl
中有一个 RadGridView
,它在 RadPageView
中的 RadPageViewPage
上,而后者又嵌套在另一个 RadPageViewPage
中RadPageView
。下面的代码基本上只是处理一个装在它自己的透明窗体中的加载微调器。当然,它总是在自己的线程上调用。
private static void RunWaiting(Control c, string text)
{
wf = new WaitingForm();
wf.drwbieSpinnerFrame.Text = text;
wf.ShowInTaskbar = false;
wf.Left = c.Left + (c.Width / 2);
wf.Top = c.Top + (c.Height / 2);
wf.Width = c.Width;
wf.Height = c.Height;
wf.FormBorderStyle = FormBorderStyle.None;
wf.ControlBox = false;
wf.TopMost = true;
wf.StartPosition = FormStartPosition.Manual;
Application.Run(wf);
}
显然,我希望微调器 (WaitForm
) 按需显示在控件的中心。如果我将容纳 RadGridView
的主 UserControl
传递给它,我也可以将它传递给该控件的父控件并以 RadPageViewPage
为中心。如果我将此方法传递给 RadGridView
,微调器根本不会出现,即使调用了代码并且仍然设置了“wf
”的属性。谁能告诉我我错过了什么?
不幸的是,耗时的任务本身正在更新 UI 并且由于其他原因必须存在于 UI 线程上,但我能够通过使用递归 class 这让我得到了适当的 (x,y) 坐标来在控件中间显示一个表单。
private static void RunWaiting(Control c, string text)
{
wf = new WaitingForm();
wf.drwbieSpinnerFrame.Text = text;
wf.ShowInTaskbar = false;
int[] tl = GetTopLefts(c);
wf.Top = (tl[0] + (c.Height / 2)) - (wf.Height / 2);
wf.Left = (tl[1] + (c.Width / 2)) - (wf.Width / 2);
wf.FormBorderStyle = FormBorderStyle.None;
wf.ControlBox = false;
wf.TopMost = true;
wf.StartPosition = FormStartPosition.Manual;
IsHolding = true;
Application.Run(wf);
}
以及获取位置数据调用的方法:
private static int[] GetTopLefts(Control c)
{
int top, left;
top = c.Top;
left = c.Left;
if (c.Parent != null)
{
int[] parentPoint = GetTopLefts(c.Parent);
top += parentPoint[0];
left += parentPoint[1];
}
return new int[] { top, left };
}
您可以通过将 GetTopLefts()
的最终输出设为 Point
来很好地解决这个问题,但这种方式的某些方面感觉更可靠。