2017-09-14 34 views
0

我有3個窗體:A,B,C在子窗體隱藏後,父項未激活

Form1 A;

Form2 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(); 
    } 
} 
  1. 當應用程序開始,形式A是節目。
  2. 我打開另一個程序(例如:CMD),以活性cmd窗口
  3. 我點擊形式A,至活性形式的
  4. 我點擊按鈕ShowBC - > showBC_Click
  5. 形式B和C被示出
  6. 我按一下按鈕隱藏基於C則B會被激活,
  7. 我點擊B鍵隱藏,我希望A激活(你這麼認爲嗎?)
  8. cmd窗口被激活

// ==============================================

@Sinatr 我有僅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"); 
    } 
} 
  1. 當應用程序開始,形式A是節目。
  2. 我打開另一個程序(例如:CMD),以活性cmd窗口
  3. 我點擊形式A,至活性形式的
  4. 我點擊按鈕ShowB - > showB_Click
  5. 形式B被示出
  6. 我點擊B型
  7. 的MessageBox 「測試」 顯示
  8. 我點擊消息框
  9. 消息框關閉按鈕OK按鈕MSGBOX
  10. 我點擊按鈕隱藏在B和希望A激活
  11. cmd窗口被激活

我預計是在最後一步

解決方案有效(你這麼認爲嗎?): 因爲某些子窗口不是窗體,比如SelectColor Dialog,所以我需要使用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); 
     } 
    } 
+0

你知道有一個「Z層」排序?這意味着如果你關閉/隱藏當前最頂層的窗口,它將會聚焦(激活)下面的窗口? ** MAGIC ** –

+0

我知道,但我認爲下面的窗口是A,而不是cmd –

+0

如果你不嘲笑'Owner'和'Visible'並使用Show()和Close( )'? – GSerg

回答

2

我能夠重現該問題。

它應該是與激活Owner多個形式具有相同的所有者,因爲它只有一個Form2正常工作。

這裏的錯誤是,如果其中一個關閉,另一個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(); 
} 
+0

謝謝,你知道究竟是什麼問題嗎?我需要一個解釋給我的客戶,我試圖找到任何有關此msdn文件,但沒有找到:( –

+0

此外,我有同樣的問題,只有A, B.不需要C.我會添加到第一個職位 –

+0

不要說明什麼,解決問題,你想要哪種行爲?看編輯 – Sinatr

1

你離開它的操作系統要弄清楚哪個窗口時,一個與重點消失應該被激活。它在這裏所做的肯定不會贏得任何獎品。另外一個相當大的問題與WPF對話順便說一句。 準確地爲什麼這樣做很難猜測,它似乎並沒有足夠的重視窗戶所有者。請注意,當你最小化窗口而不是隱藏它時,它工作得很好,爲什麼這種行爲不同,這很奇怪。讓我們毫不猶豫地稱它爲一個錯誤。

解決方法是相當直接的,只是不要強迫它本身找到另一個窗口:

if (this.Owner != null) this.Owner.Activate(); 
    this.Hide(); 

此外,在一個WPF應用程序的解決方案。

+0

謝謝,最後我需要修復每個子窗口。我試過你的解決方案,但在某些情況下,它不起作用。我會在我的回答中解釋 –