C# 隐藏子窗体后,不激活父窗体
我有3张表格:A、B、C 表格1 A 表格2 B,C A是B和C的父代C# 隐藏子窗体后,不激活父窗体,c#,winforms,C#,Winforms,我有3张表格:A、B、C 表格1 A 表格2 B,C A是B和C的父代 public partial class Form1 : Form { Form2 formB = null; Form2 formC = null; public Form1() { InitializeComponent(); formB = new Form2(); formB.Owner = this; formC =
public partial class Form1 : Form
{
Form2 formB = null;
Form2 formC = null;
public Form1()
{
InitializeComponent();
formB = new Form2();
formB.Owner = this;
formC = new Form2();
formC.Owner = this;
}
private void showBC_Click(object sender, EventArgs e)
{
formB.Visible = true;
formC.Visible = true;
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void hide_Click(object sender, EventArgs e)
{
this.Hide();
}
}
public partial class Form1 : Form
{
Form2 formB = null;
public Form1()
{
InitializeComponent();
formB = new Form2();
formB.Owner = this;
}
private void showB_Click(object sender, EventArgs e)
{
formB.Visible = true;
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void hide_Click(object sender, EventArgs e)
{
this.Hide();
}
private void MsgBox_Click(object sender, EventArgs e)
{
MessageBox.Show("Test");
}
}
[DllImport("user32.dll")]
private static extern IntPtr GetTopWindow(IntPtr parentHandle);
private static uint GW_HWNDNEXT = 2;
[DllImport("user32.dll")]
private static extern IntPtr GetWindow(IntPtr hWnd, uint wCmd);
[DllImport("user32.dll")]
private static extern int IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern IntPtr SetFocus(IntPtr parentHandle);
[DllImport("user32.dll")]
private static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);
public static void SetAppFocus()
{
IntPtr topWindowHandle = GetTopWindow(IntPtr.Zero);
while (topWindowHandle != null)
{
if (IsWindowVisible(topWindowHandle) != 0)
{
int currentProcessId = Process.GetCurrentProcess().Id;
int processId = 0;
GetWindowThreadProcessId(topWindowHandle, out processId);
if (processId == currentProcessId)
{
SetFocus(topWindowHandle);
break;
}
}
// goto next window
topWindowHandle = GetWindow(topWindowHandle, GW_HWNDNEXT);
}
}
我能够重现这个问题 当多个表单具有相同的所有者时,它应该与激活
所有者相关,因为它只适用于一个表单2
这里的错误是,如果其中一个关闭,另一个Form2
被激活
设法
void showBC_Click(object sender, EventArgs e)
{
B.Visible = C.Visible = true;
Activate();
}
现在一切都“正常”了:关闭Form2
将激活所有者
如果您希望保持原始行为,那么这里有一个解决方法:
public Form1()
{
InitializeComponent();
formB = new Form2 { Owner = this };
formC = new Form2 { Owner = this };
formB.VisibleChanged += Child_VisibleChanged;
formC.VisibleChanged += Child_VisibleChanged;
}
void Child_VisibleChanged(object sender, EventArgs e)
{
if (!Application.OpenForms.Cast<Form>().OfType<Form2>().Any(o => o.Visible))
Activate();
}
public Form1()
{
初始化组件();
formB=newform2{Owner=this};
formC=newform2{Owner=this};
formB.VisibleChanged+=子项\u VisibleChanged;
formC.VisibleChanged+=子项\u VisibleChanged;
}
无效子项\u VisibleChanged(对象发送方,事件参数e)
{
if(!Application.OpenForms.Cast().OfType().Any(o=>o.Visible))
激活();
}
我能够重现这个问题
当多个表单具有相同的所有者时,它应该与激活所有者相关,因为它只适用于一个表单2
这里的错误是,如果其中一个关闭,另一个Form2
被激活
设法
void showBC_Click(object sender, EventArgs e)
{
B.Visible = C.Visible = true;
Activate();
}
现在一切都“正常”了:关闭Form2
将激活所有者
如果您希望保持原始行为,那么这里有一个解决方法:
public Form1()
{
InitializeComponent();
formB = new Form2 { Owner = this };
formC = new Form2 { Owner = this };
formB.VisibleChanged += Child_VisibleChanged;
formC.VisibleChanged += Child_VisibleChanged;
}
void Child_VisibleChanged(object sender, EventArgs e)
{
if (!Application.OpenForms.Cast<Form>().OfType<Form2>().Any(o => o.Visible))
Activate();
}
public Form1()
{
初始化组件();
formB=newform2{Owner=this};
formC=newform2{Owner=this};
formB.VisibleChanged+=子项\u VisibleChanged;
formC.VisibleChanged+=子项\u VisibleChanged;
}
无效子项\u VisibleChanged(对象发送方,事件参数e)
{
if(!Application.OpenForms.Cast().OfType().Any(o=>o.Visible))
激活();
}
您将由操作系统决定当焦点消失时应激活哪个窗口。它在这里所做的肯定不会赢得任何奖品。顺便说一句,WPF对话框也有一个相当大的问题。很难猜测它为什么会这样做,只是它似乎没有对窗口所有者给予足够的关注。请注意,当你最小化窗口而不是隐藏它时,它工作得很好,为什么会有不同的行为,嗯,很奇怪。让我们毫不犹豫地称之为bug
解决方法非常简单,只是不要强迫它自己找到另一个窗口:
if (this.Owner != null) this.Owner.Activate();
this.Hide();
还有WPF应用程序中的解决方案。您将由操作系统决定当焦点消失时应激活哪个窗口。它在这里所做的肯定不会赢得任何奖品。顺便说一句,WPF对话框也有一个相当大的问题。很难猜测它为什么会这样做,只是它似乎没有对窗口所有者给予足够的关注。请注意,当你最小化窗口而不是隐藏它时,它工作得很好,为什么会有不同的行为,嗯,很奇怪。让我们毫不犹豫地称之为bug
解决方法非常简单,只是不要强迫它自己找到另一个窗口:
if (this.Owner != null) this.Owner.Activate();
this.Hide();
还有WPF应用程序中的解决方案。您知道有“z层”排序吗?这意味着,如果关闭/隐藏当前最顶部的窗口,它将聚焦(激活)正下方的窗口?MAGICI知道,但我认为下面的窗口是一个CMD,而不是一个CMD。如果你不与所有者和可见的打交道,只使用Show()
和Close()
?@m.rogalski,会发生什么。这是我维护的应用程序中的错误。我的客户需要知道原因,所以我需要向他解释。上面的例子是一个简单的应用程序来显示这个bug,但我不知道它是否是微软的bug。你知道有一个“z层”排序吗?这意味着,如果关闭/隐藏当前最顶部的窗口,它将聚焦(激活)正下方的窗口?MAGICI知道,但我认为下面的窗口是一个CMD,而不是一个CMD。如果你不与所有者和可见的打交道,只使用Show()
和Close()
?@m.rogalski,会发生什么。这是我维护的应用程序中的错误。我的客户需要知道原因,所以我需要向他解释。上面的例子是一个简单的应用程序来显示这个bug,但我不知道它是否是微软的bug。谢谢,你知道到底是什么问题吗?我需要向我的客户解释,我试图找到任何有关此的msdn文档,但没有找到:(另外,我只有A,B有相同的问题。不需要C。我将添加到第一个帖子不解释任何内容,修复问题。你想要什么行为?请参阅编辑。谢谢,最后我需要修复每个子窗口。我尝试了你的解决方案,