Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 隐藏子窗体后,不激活父窗体_C#_Winforms - Fatal编程技术网

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 =

我有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 = 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();
    }
} 
  • 当应用程序启动时,将显示表格A
  • 我打开另一个程序(例如:cmd),以激活cmd窗口
  • 我点击表格A,激活表格A
  • 我点击按钮ShowBC->ShowBC\u点击
  • 表格B和C如图所示
  • 我点击C上的隐藏按钮,然后B被激活
  • 我单击B上的隐藏按钮,希望A处于活动状态(你这么认为?)
  • cmd窗口处于活动状态
  • //==============================================

    @西纳特 我对A和B表格也有同样的问题

    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");
        }
    } 
    
  • 当应用程序启动时,将显示表格A
  • 我打开另一个程序(例如:cmd),以激活cmd窗口
  • 我点击表格A,激活表格A
  • 我点击按钮ShowB->ShowB\u点击
  • 表格B如图所示
  • 我点击表格B上的MsgBox按钮
  • 显示消息框“测试”
  • 我单击MessageBox上的“确定”按钮
  • Messagebox已关闭
  • 我单击B上的隐藏按钮,希望A处于活动状态(你这么认为?)
  • cmd窗口处于活动状态
  • 我希望A在最后一步中处于活动状态

    解决方案: 因为有些子窗口不是窗体,比如SelectColor对话框。。所以我需要使用win32 api列出子窗口来激活它们。 在每个子表单中,我都需要这样做:

        [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。我将添加到第一个帖子不解释任何内容,修复问题。你想要什么行为?请参阅编辑。谢谢,最后我需要修复每个子窗口。我尝试了你的解决方案,