2017-09-14 9 views
0

私は3つのフォームを持っています:A、B、C子フォームが隠された後、親はアクティブ化されません

Form1;

Form2B、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は、ショーです。 > showBC_Click
  2. 形態BおよびCに示される - は、IボタンをクリックShowBC、アクティブCMDウィンドウ
  3. にIが活性型
  4. に、フォームAをクリックしてください。私は別のプログラム(CMD EX)を開き
  5. 私はBが
  6. 私はBのボタンの非表示をクリックしactivedされ、その後C上のボタンを非表示をクリックして、私はAがアクティブであると思います(あなたがそう思う?)
  7. 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. にIが活性型に、フォームAにIがボタンShowBをクリック
  4. クリック - > showB_Click
  5. フォームBが
  6. が示されて
  7. 私は
  8. Messageboxはが閉じられる
  9. メッセージボックスで[OK]ボタンをクリック
  10. 示されている形態B
  11. メッセージボックス "テスト" のボタンのメッセージボックスをクリック
  12. 私はBのボタンの非表示をクリックして、私はAがアクティブであると思います
  13. CMDウィンドウがアクティブである

私はAが最終段階

ソリューションでアクティブになっている期待(あなたがそう思います?): 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

私は問題を再現することができました。それはちょうど1 Form2で正しく動作しますので、それは、Ownerときつ以上のフォームを活性化に関連したものになるはずです

は、同じ所有者を持っています。

ここでは、どちらか一方がクローズされている場合は別のForm2がアクティブになります。どちらか閉じForm2して所有者をアクティブにします:

は今、すべてが "適切に" 働く

void showBC_Click(object sender, EventArgs e) 
{ 
    B.Visible = C.Visible = true; 
    Activate(); 
} 

してみてください。


あなたはここで、元の動作を維持したい場合は、回避策です:

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

また、私は、 B.必要ありませんC.最初の投稿に追加します –

+0

何も説明せずに問題を解決してくださいどのような振る舞いが必要ですか編集を参照してください – Sinatr

1

あなたが焦点との1が消えたときにアクティブにすべきウィンドウを把握するOSをそれを残しています。それが確かに賞品を獲得するわけではありません。また、WPFダイアログのかなり大きな問題がbtw。 正確にはこれはこれを推測するのが難しいのですが、それはウィンドウの所有者に十分注意を払うようには見えません。それを隠すのではなくウィンドウを最小化するときにうまく動作すること、違う動作がなぜうまくいくのか、ということに注意してください。それをバグと呼ぶことを躊躇しないでください。

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

また、WPFアプリで解決策を:

この問題を回避するには、単にそれ自体で別のウィンドウを見つけるために、それを強制していない、かなりストレートフォワードです。

+0

ありがとう、最後に私はすべての子ウィンドウを修正する必要があります。私はあなたの解決策を試しましたが、場合によってはうまくいきません。私は私の答えで説明します –

関連する問題