2011-06-20 14 views
23

Używam Window.ShowDialog() do otwierania okna modalnego w mojej aplikacji WPF (MVVM), ale pozwala mi to przejść do innych okien przy użyciu paska zadań Windows (Windows 7).Modalne okno dialogowe niewidoczne na innych oknach

Rozważ to: Mam 3 okna niemodalne otwarte w mojej aplikacji. Teraz Jedno z nich otwiera okno modalne przy użyciu Window.ShowDialog(). Ustawiłem też jako właściciela okna modemu Application.MainWindow. Dzieje się tak, ponieważ używam komunikatów MVVM, a program obsługi wiadomości otwierający nowe okno jest scentralizowany pod numerem App.xaml.cs. Okno otwiera się modalnie - bez problemów. Jednak Windows 7 pozwala mi przełączać się do innych okien aplikacji z paska zadań. Prowadzi to do sytuacji, w której okno modalne znajduje się za innym oknem, które wolę nie mieć.

Nie mogę zrobić niczego w innych oknach, o ile mam otwarty modal, ale byłoby miło, gdyby okno modalne zawsze pozostało na górze tak długo, jak długo jest otwarte. Czy jest sposób, w jaki mogę wyłączyć przełączanie paska zadań, gdy modalny jest otwarty? FYI - wszystkie otwarte okna uruchomione z aplikacji pojawiają się jako osobne wpisy na pasku zadań.

Z góry dziękuję!

+0

Czy możemy uzyskać kod z miejsca utworzenia okna, które staje się dialogiem modalnym? – user7116

+0

Potrzebne było, aby okno było ponad WSZYSTKIE inne aplikacje. Potrzebuję, aby okno było nad jakimkolwiek innym oknem w aplikacji, takim jak okno dialogowe. Dla moich wymagań te dwie linie: Owner = Application.Current.MainWindow; i ShowInTaskbar = false; działa dobrze. +1 dla ciebie. –

Odpowiedz

55

Nie ma żadnego kodu oprzeć ten off, ale to brzmi jak masz w lewo wyłączyć niektóre właściwości na Window utworzone i oczekuje ShowDialog zastosowanie dodatkowych „Dialog” semantyki:

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

Jesteś zbawicielem sześciocylindrowych! Najważniejsze było to, czego mi brakowało. Przepraszam, że nie wysłałem kodu, ale go przybiłeś. Nie mogę uwierzyć, że to przegapiłem. Dzięki jeszcze raz! – Pratz

+0

Aby usunąć przyciski napisów, należy ustawić jego 'ResizeMode' na' NoResize' zamiast 'WindowStyle'. ToolWindow nie jest dialogiem. –

+0

@DavidAnderson: Brzmi nieźle, pod warunkiem, że nie chcesz zmienić rozmiaru okna dialogowego. – user7116

9

Ustawienie Najwyższy na Prawdziwy (Najwyższy = Prawdziwy) powoduje, że okno dialogowe znajduje się na górze wszystkich okien w systemie (nie tylko w aplikacji).

Więc można spróbować zarejestrować zdarzenie aktywowany w głównym oknie:

Activated += WindowActivated; 

i aktywować okno właściciel modalnego okna dialogowego za każdym razem, gdy stają się aktywne inny główne okno aplikacji.

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(); 
    } 
} 

Ten prosty hack zakłada, że ​​wszystkie okna Twoich dzieci są modalne, ale możesz napisać bardziej wyrafinowaną logikę.

+1

to powinna być zaakceptowana odpowiedź: wydaje się, że jedynym sposobem jest pozostawienie okna dialogowego na głównym oknie po aktywacji aplikacji za pomocą paska zadań. Jest to znany problem: http://connect.microsoft.com/VisualStudio/feedback/details/474480/wpf-showdialog-and-owner – stijn

+0

Działa to lepiej z kodu źródłowego samego okna dialogowego (używając + = zdarzenia). Dzięki temu główne okno nie obchodzi, co robią inne okna. – Grault

+0

Och, i aktywowanie okna dialogowego, gdy jest ukryte (ponieważ nie lubię go faktycznie zamykać) powoduje, że główne okno nie działa, więc sprawdzenie IsVisible jest w porządku. – Grault

10

Wystarczy ustawić właściwość właściciela okna na okno wywoływania. Wtedy aktywacja aplikacji WPF na pasku zadań nie tylko aktywuje MainWindow, ale także modalne okno potomne i przenosi je na wierzch.

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

Musiałem zrobić trochę modyfikacji. Musiałem ustawić właściciela i aktywować okno. Sprawdź okno podręczne i uaktywnij okno zgodnie z poniższym opisem.

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

Skończyło się na połączeniu kilku odpowiedzi tutaj. Przyjęta odpowiedź była na początku użyteczna, ale jak inni ludzie tutaj wskazali, ustawienie Topmost = true oznacza, że ​​okno jest zawsze powyżej innych uruchomionych aplikacji.Moje rozwiązanie było to:

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

początkowo używany:

myWindow.Owner = Application.Current.MainWindow; 

Jednak ta metoda powoduje problemy, jeśli masz trzy otwarte okna tak:

MainWindow 
    | 
    -----> ChildWindow1 

       | 
       -----> ChildWindow2 

następnie ustawienie ChildWindow2.Owner = Application.Current.MainWindow ustawi właścicielem okna, które ma być jego nadrzędnym oknem, a nie nadrzędnym.

Aby przyspieszyć działanie, dodałem go jako fragment kodu w Visual Studio. Jeśli dodać następujące polecenie Narzędzia -> Code Snippet Manager -> Moje Fragmenty kodu:

<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> 

wpisując „właściciel” i dwukrotnie naciskając klawisz Tab doda „” Application.CurrentWindows... udział w automatycznie.

+1

ten uratował mi życie, ponieważ ustawiłem wszystkie opcje wymienione przez wszystkich i nigdy nie patrzyłem, jakie może być główne okno. twoja odpowiedź doprowadziła mnie do tego –

Powiązane problemy