我已经设置了一个自定义控件,该控件充当加载叠加层,该叠加层是一个带有图片框的窗体,用于显示图像。
当叠加层显示出来时,它就位并且位于调用它的主要表单的前面,这看起来很棒。但是,当用户移动表单或调整表单大小时,表单将退回到主表单。
当主窗体正在移动或调整大小时,叠加窗体移动并调整大小不会出现问题,但是在完成大小调整或移动之后,窗体会落后于主窗体。如何在不使用TopMost的情况下将叠加层表单放回顶部?
我使用以下方法从主表单中调用以下代码
LoadingControl p = new LoadingControl(dataGridView1, this);
p.Show();
和叠加形式:
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class LoadingControl : Form
{
private Color BackgroundColour = Color.Black;
private double BackgroundOpacity = 0.50;
private Image LoadingImage = APPNAME.Properties.Resources.loading_120x128;
private Form Mainform;
private Control MainControl;
public LoadingControl(Control parent, Form frm)
{
MainControl = parent;
Mainform = frm;
SetupForm();
Size = parent.ClientSize;
Location = parent.PointToScreen(Point.Empty);
Mainform.Move += AdjustPosition;
MainControl.SizeChanged += AdjustPosition;
}
private void SetupForm()
{
FormBorderStyle = FormBorderStyle.None;
BackColor = BackgroundColour;
Opacity = BackgroundOpacity;//0.50;
ShowInTaskbar = false;
StartPosition = FormStartPosition.Manual;
PictureBox pbox = new PictureBox {Image = LoadingImage, Parent = this};
pbox.Width = pbox.Image.Width;
pbox.Height = pbox.Image.Height;
pbox.Left = (Width/2) - (pbox.Width/2);
pbox.Top = (Height/2) - (pbox.Height/2)-10;
pbox.Anchor = AnchorStyles.None;
Controls.Add(pbox);
}
public void SetLoadingImage(Image img)
{
LoadingImage = img;
}
public void SetBackgroundColour(Color col)
{
BackgroundColour = col;
}
public void SetOpacity(double Opa)
{
BackgroundOpacity = Opa;
}
private void AdjustPosition(object sender, EventArgs e)
{
//TopMost = true;
BringToFront();
ClientSize = MainControl.ClientSize;
Location = MainControl.PointToScreen(Point.Empty);
//Mainform.Activate();
//TopMost = false;
BringToFront();
Focus();
//MakeTopMost(this);
}
}
无论您调用多少次BringToFront()
,都不会将您的表单移到活动表单的顶部。BringToFront()
不会使控件成为顶级控件,也不会引发Paint事件。
有太多方法可以解决它。IMO的最佳方法是使加载控件成为主窗体的子控件,而不是使它们分开,并且在每次移动或调整大小后都必须手动放置控件。
可以执行的另一种方法是,在每次移动,调整大小或最大化/最小化事件发生后,更改控制窗口的z顺序并激活它。
这可以通过一点点p调用来实现:
public void FocusForm()
{
// force window to have focus
uint foreThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
uint appThread = GetCurrentThreadId();
const uint SW_SHOW = 5;
if (foreThread != appThread)
{
AttachThreadInput(foreThread, appThread, true);
BringWindowToTop(this.Handle);
ShowWindow(this.Handle, SW_SHOW);
AttachThreadInput(foreThread, appThread, false);
}
else
{
BringWindowToTop(this.Handle);
ShowWindow(this.Handle, SW_SHOW);
}
this.Activate();
}
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
[DllImport("kernel32.dll")]
static extern uint GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
[DllImport("user32.dll", SetLastError = true)]
static extern bool BringWindowToTop(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
我用它来设置我的主窗口在开始时是最顶部的,因此您可能想Activate()
在最后丢失通话。
我必须说,即使这可能对您有用[我还没有完全测试它的移动和调整大小],但我还是建议您修改代码,并将加载控件表单作为主表单中的子控件。
编辑:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句