2011-06-20 35 views
23

Tôi đang sử dụng Window.ShowDialog() để mở một cửa sổ phương thức trong ứng dụng WPF (MVVM), nhưng nó cho phép tôi điều hướng đến các cửa sổ khác bằng thanh tác vụ Windows (Windows 7).Modal Dialog không hiển thị trên các cửa sổ khác

Hãy xem xét điều này: Tôi có 3 cửa sổ không theo kiểu mở trong ứng dụng của tôi. Bây giờ một trong số này sẽ mở ra một cửa sổ phương thức bằng cách sử dụng Window.ShowDialog(). Tôi cũng đặt Application.MainWindow làm chủ sở hữu của cửa sổ phương thức. Điều này là như vậy bởi vì tôi đang sử dụng tin nhắn MVVM và trình xử lý tin nhắn để mở một cửa sổ mới được tập trung trong App.xaml.cs. Cửa sổ mở ra một cách bình thường - không có vấn đề ở đó. Tuy nhiên, Windows 7 cho phép tôi chuyển sang các cửa sổ ứng dụng khác từ thanh tác vụ. Điều này dẫn đến một tình huống mà cửa sổ phương thức đi sau một cửa sổ khác, mà tôi không muốn có.

Tôi không thể làm bất cứ điều gì trên các cửa sổ khác miễn là tôi có phương thức mở, nhưng sẽ rất tuyệt nếu cửa sổ phương thức luôn ở trên đầu miễn là cửa sổ mở. Có cách nào tôi có thể vô hiệu hóa thanh tác vụ chuyển đổi khi phương thức được mở? FYI - tất cả các cửa sổ đang mở được khởi chạy từ ứng dụng xuất hiện dưới dạng các mục riêng biệt trên thanh tác vụ.

Cảm ơn trước!

+0

Chúng tôi có thể lấy một số mã từ nơi bạn tạo Cửa sổ trở thành hộp thoại phương thức không? – user7116

+0

Điều bạn cần là cửa sổ ở trên TẤT CẢ các ứng dụng khác. Những gì tôi cần là cho cửa sổ ở trên bất kỳ cửa sổ nào khác trong ứng dụng, như cửa sổ hộp thoại. Đối với các yêu cầu của tôi, hai dòng này: Owner = Application.Current.MainWindow; và ShowInTaskbar = false; hoạt động tốt. 1 cho bạn. –

Trả lời

55

Không có bất kỳ mã để căn này khỏi, nhưng có vẻ như bạn đã rời đi một số tài sản trên các Window bạn đã tạo và dự kiến ​​ShowDialog để áp dụng bổ sung "thoại" ngữ nghĩa:

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

Bạn là một sáu bản sao cứu tinh! Trên cùng là những gì tôi đã mất tích. Xin lỗi vì đã không đăng mã nhưng bạn đã đóng đinh nó. Không thể tin rằng tôi đã bỏ lỡ nó. Cảm ơn một lần nữa! – Pratz

+0

Để loại bỏ các nút chú thích, bạn cần đặt 'ResizeMode' thành' NoResize' thay cho 'WindowStyle'. ToolWindow không phải là một hộp thoại. –

+0

@DavidAnderson: âm thanh tốt, miễn là bạn không quan tâm để thay đổi kích thước hộp thoại. – user7116

9

Đặt Topmost to True (Trên cùng = True) khiến hộp thoại nằm trên đầu tất cả các cửa sổ trong hệ thống (không chỉ trong ứng dụng).

Vì vậy, bạn có thể thử để đăng ký sự kiện hoạt tính trong cửa sổ chính của bạn:

Activated += WindowActivated; 

và kích hoạt một cửa sổ chủ sở hữu của hộp thoại modal mỗi khi một cửa sổ chính của ứng dụng của bạn trở nên năng động.

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

Hack đơn giản này giả định tất cả cửa sổ con của bạn là phương thức nhưng bạn có thể viết một logic phức tạp hơn.

+1

đây phải là câu trả lời được chấp nhận: có vẻ như cách duy nhất để giữ cửa sổ hộp thoại ở phía trên cửa sổ chính sau khi kích hoạt ứng dụng bằng thanh tác vụ. Đó là một vấn đề đã biết: http://connect.microsoft.com/VisualStudio/feedback/details/474480/wpf-showdialog-and-owner – stijn

+0

Điều này hoạt động tốt hơn từ codebehind của chính hộp thoại đó (sử dụng + = trên sự kiện). Điều đó cho phép cửa sổ chính không quan tâm đến những cửa sổ khác đang làm gì. – Grault

+0

Ồ, và kích hoạt hộp thoại trong khi hộp thoại bị ẩn (vì tôi không thích đóng cửa sổ) khiến cửa sổ chính không hoạt động được, vì vậy bạn có thể kiểm tra IsVisible theo thứ tự. – Grault

10

Chỉ cần đặt thuộc tính chủ sở hữu của Cửa sổ thành cửa sổ gọi. Sau đó kích hoạt ứng dụng WPF trong thanh tác vụ không chỉ kích hoạt MainWindow mà còn là cửa sổ con phương thức và đưa nó lên phía trước.

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

Phải làm một chút sửa đổi. Tôi phải đặt chủ sở hữu và kích hoạt cửa sổ. Kiểm tra cửa sổ bật lên và kích hoạt cửa sổ như được đưa ra bên dưới.

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

Tôi đã kết thúc bằng cách sử dụng kết hợp một vài câu trả lời ở đây. Câu trả lời được chấp nhận là hữu ích lúc đầu nhưng như những người khác ở đây đã chỉ ra thiết lập Topmost = true có nghĩa là cửa sổ luôn ở trên bất kỳ ứng dụng nào khác đang chạy.Giải pháp của tôi là thế này:

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

tôi ban đầu được sử dụng:

myWindow.Owner = Application.Current.MainWindow; 

Tuy nhiên, phương pháp này gây ra vấn đề nếu bạn có ba cửa sổ mở như thế này:

MainWindow 
    | 
    -----> ChildWindow1 

       | 
       -----> ChildWindow2 

Sau đó thiết lập ChildWindow2.Owner = Application.Current.MainWindow sẽ thiết lập chủ sở hữu của cửa sổ là cửa sổ ông bà, không phải cửa sổ chính.

Để tăng tốc mọi thứ, tôi đã thêm nó dưới dạng đoạn mã trong Visual Studio. Nếu bạn thêm dòng sau vào Tools -> Code Snippet Manager -> My Code Snippets:

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

Gõ 'chủ nhân' và nhấn đúp phím tab sẽ thêm 'Application.CurrentWindows...' gia cho bạn tự động.

+1

điều này đã cứu mạng tôi bởi vì tôi đã thiết lập tất cả các tùy chọn được đề cập bởi tất cả mọi người và nhưng không bao giờ nhìn những gì mainwindow có thể được. câu trả lời của bạn đã dẫn tôi đến đó –

Các vấn đề liên quan