2011-06-20 42 views
23

私はWPF(MVVM)アプリケーションでモーダルウィンドウを開くのにWindow.ShowDialog()を使用していますが、Windowsタスクバー(Windows 7)を使用して他のウィンドウにナビゲートできます。他のウィンドウの上にモーダルダイアログが表示されない

これを考慮してください: 私は3つの非モーダルウィンドウを自分のアプリケーションで開いています。今、これらのうちの1つがWindow.ShowDialog()を使ってモーダルウィンドウを開きます。私はまた、Application.MainWindowをモーダルウィンドウの所有者に設定しました。これは、私がMVVMメッセージングを使用していて、新しいウィンドウを開くためのメッセージハンドラがApp.xaml.csに集中しているためです。ウィンドウはモーダルで開きますが、問題はありません。しかし、Windows 7では、タスクバーから他のアプリケーションウィンドウに切り替えることができます。これは、モーダルウィンドウが別のウィンドウの後ろに来る状況につながります。

私はモーダルを開いている限り、他のウィンドウで何もできませんが、モーダルウィンドウが開いている限り、モーダルウィンドウが常に上に残っているといいでしょう。モーダルが開いているときにタスクバーの切り替えを無効にする方法はありますか? FYI - アプリから起動したすべての開いているウィンドウは、タスクバーに別々のエントリとして表示されます。

ありがとうございます!

+0

モーダルダイアログになるウィンドウを作成する場所からコードを取得できますか? – user7116

+0

あなたが必要としたのは、そのウィンドウが他のすべてのアプリケーションの上にあることでした。私が必要とするのは、ウィンドウがダイアログウィンドウのように、アプリケーションの他のウィンドウの上にあることです。私の要件のために、これら2つの行:Owner = Application.Current.MainWindow; ShowInTaskbar = false;うまくいく。 +1してください。 –

答えて

55

ありのオフこれをベースにする任意のコードはありませんが、追加の「ダイアログ」のセマンティクス適用するShowDialogを作成したWindow上のいくつかのプロパティをオフに左にと期待しているように聞こえる:

Window window = new Window() 
{ 
    Title = "Modal Dialog", 
    ShowInTaskbar = false,    // don't show the dialog on the taskbar 
    Topmost = true,      // ensure we're Always On Top 
    ResizeMode = ResizeMode.NoResize, // remove excess caption bar buttons 
    Owner = Application.Current.MainWindow, 
}; 

window.ShowDialog(); 
+0

あなたは救い主の6文字変数です!最上級は私が逃したものでした。コードを投稿しないのにあなたはそれを釘付けにしたことに対する謝罪。私はそれを逃したと信じられない。再度、感謝します! – Pratz

+0

キャプションボタンを削除するには、 'ResizeMode'を' WindowStyle'ではなく 'NoResize'に設定する必要があります。 ToolWindowはダイアログではありません。 –

+0

@DavidAnderson:ダイアログのサイズを気にしなければ、良いと思います。 – user7116

9

TopmostをTrue(Topmost = True)に設定すると、ダイアログはアプリケーション内だけでなく、システム内のすべてのウィンドウの上部に表示されます。

つまり、あなたのメインウィンドウで活性化イベント登録しようとすることができます

Activated += WindowActivated; 

をし、モーダルダイアログのオーナウィンドウに、アプリケーションの別のメインウィンドウがアクティブになるたびに起動します。

private void WindowActivated(object sender, EventArgs e) 
{ 
    Window window = Application.Current.Windows.OfType<YourMainWindow>().FirstOrDefault(p => p != this && !p.IsActive && p.OwnedWindows.Count > 0); 
    if (window != null) 
    { 
     window.Activate(); 
    } 
} 

この単純なハックは、すべての子供のウィンドウがモーダルであることを前提としていますが、より洗練されたロジックを書くことができます。

+1

これは受け入れられる回答でなければなりません。タスクバーを使用してアプリケーションを起動した後に、メインウィンドウの上にダイアログウィンドウを維持する唯一の方法と思われます。これは既知の問題です:http://connect.microsoft.com/VisualStudio/feedback/details/474480/wpf-showdialog-and-owner – stijn

+0

これは、ダイアログボックスのコードビハインド(イベントで+ =を使用)より優れています。これにより、メインウィンドウは他のウィンドウが何をしているのか気にしません。 – Grault

+0

ああ、隠している間にダイアログをアクティブにすると(実際に閉じたくないため)、メインウィンドウが操作不能になるので、IsVisibleのチェックが順調です。 – Grault

10

ウィンドウの所有者プロパティを呼び出しウィンドウに設定するだけです。その後、タスクバーでWPFアプリケーションをアクティブにするだけで、MainWindowをアクティブにするだけでなく、モーダル子ウィンドウもアクティブにして前面に表示されます。

ChildWindow C = new ChildWindow(); 
C.Owner = this; 
C.ShowDialog(); 
1

少し修正する必要がありました。 私はオーナーを設定してウィンドウをアクティブにしなければなりませんでした。 ポップアップウィンドウを確認し、下記のようにウィンドウをアクティブにします。

 var enumerator = Application.Current.Windows.GetEnumerator(); 
     while (enumerator.MoveNext()) 
     { 
      Window window = (Window)enumerator.Current; 
      if (window != null && window.GetType() == typeof(PopUpWindow)) 
      { 
       window.Activate(); 
      } 
     } 
3

私はここでいくつかの回答を組み合わせて使用​​しました。受け入れられた答えは最初は便利でしたが、ここにある他の人が設定したように指摘されているように、Topmost = trueは、そのウィンドウが常に他の実行中のアプリケーションの上にあることを示します。

var myWindow = new MyWindowType(); 
myWindow.Owner = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive); 

私が最初に使用:

MainWindow 
    | 
    -----> ChildWindow1 

       | 
       -----> ChildWindow2 

その後ChildWindow2.Owner = Application.Current.MainWindowを設定すると、設定されます:あなたはこのようなオープン3つのウィンドウを持っている場合

myWindow.Owner = Application.Current.MainWindow; 

しかし、この方法では問題を引き起こす私のソリューションは、このましたウィンドウの所有者は親ウィンドウではなく、その祖父ウィンドウになります。

高速化のために、Visual Studioでコードスニペットとして追加しました。あなたはツールに以下を追加した場合 - >コードスニペットマネージャ] - > [マイコードスニペット:

<CodeSnippets 
    xmlns="http://schemas.microsoft.com/VisualStudio/2010/CodeSnippet"> 
    <CodeSnippet Format="1.0.0"> 
    <Header> 
     <Title>MVVM Set owner of page to be current active window</Title> 
     <Shortcut>owner</Shortcut> 
    </Header> 
    <Snippet> 
     <Code Language="CSharp"> 
     <![CDATA[System.Windows.Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);]]> 
     </Code> 
    </Snippet> 
    </CodeSnippet> 
</CodeSnippets> 

タイピングの「所有者」とダブルタップ、タブキーは自動的にあなたのために「Application.CurrentWindows...」の部分を追加します。

+1

これは私の人生を助けました。なぜなら私は誰もが言及したすべてのオプションを設定していたからです。あなたの答えは私にそれを調べさせました –

関連する問題