2012-05-25 42 views
16

Tôi có ứng dụng sau đây đơn giản WPF:Tại sao đóng cửa sổ con cuối cùng giảm thiểu cửa sổ chính của nó?

App.xaml:

<Application x:Class="TestWpf2.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
</Application> 

App.xaml.cs:

public partial class App : Application 
{ 
    protected override void OnStartup(StartupEventArgs e) 
    { 
     var parentWindow = new Window(); 
     parentWindow.Show(); 

     var childWindow1 = new Window { Owner = parentWindow }; 
     childWindow1.Show(); 

     var childWindow2 = new Window { Owner = parentWindow }; 
     childWindow2.Show(); 
    } 
} 

Ứng dụng này gây ra 3 cửa sổ để xuất hiện trên màn hình. Nếu bạn chạy ứng dụng và đóng hai cửa sổ con, cửa sổ chính sẽ được thu nhỏ xuống thanh tác vụ. Nếu bạn nhận xét ra childWindow2.show(), hãy chạy ứng dụng và đóng cửa sổ con duy nhất, cửa sổ chính không được thu nhỏ vào thanh tác vụ.

tôi có thể thêm đoạn mã sau để làm việc xung quanh vấn đề này:

childWindow1.Closing += delegate(object sender, CancelEventArgs ex) 
{ 
    (sender as Window).Owner = null; 
}; 

nhưng tôi không muốn sử dụng một hack như thế này, và tôi muốn hiểu tại sao vấn đề này xảy ra.

Tại sao điều này lại xảy ra?

+0

Nó không được thu nhỏ, nó chỉ mất tiêu điểm và ẩn sau một cửa sổ khác. Giống như cửa sổ chính của Visual Studio. Thêm ShowActivated = false vào bộ khởi tạo cửa sổ con là một cách để sửa nó. –

+0

@HansPassant ShowActivated chỉ dừng các cửa sổ con được kích hoạt khi chúng được tạo. Nếu người dùng nhấp vào chúng để kích hoạt chúng, sau đó đóng chúng, cửa sổ chính vẫn bị mất tiêu điểm. – Oliver

+1

https://connect.microsoft.com/VisualStudio/feedback/details/523197/modal-dialog-on-top-of-non-modal-window-sends-main-window-to-back –

Trả lời

3

Điều này là do thực tế là bạn không thể sử dụng cửa sổ chính khi cửa sổ con được hiển thị với bộ Chủ sở hữu. Chỉ cần cố gắng truy cập vào cửa sổ cha mẹ trong khi đứa trẻ đang ở trên màn hình, và nó sẽ không cho phép bạn, để xem những gì tôi có ý nghĩa.

Nếu bạn không chỉ định Chủ sở hữu thì hành vi này không xảy ra.

+1

Tôi không nghĩ rằng đây là trường hợp. Với nhóm Chủ sở hữu, bạn vẫn có thể tương tác với cửa sổ chính. Cửa sổ con bị buộc phải là ontop của cha mẹ, nhưng cha mẹ vẫn phản hồi đầu vào. – Oliver

1

Tôi chưa bao giờ tìm ra nguyên nhân gây ra điều này xảy ra! Cuối cùng, tôi đã viết mã này được gọi là sau khi bất kỳ cửa sổ con bị đóng:

// App inherits from Application, and has a Window property called MainWindow 
// and a List<Window> property called OpenWindows. 
if (!App.OpenWindows.Any()) 
    App.ParentWindow.Activate(); 

Vì vậy, nếu cửa sổ con cuối cùng được đóng lại (làm App.OpenWindows.Any() false) cửa sổ cha mẹ được kích hoạt. Điều này không dẫn đến nhấp nháy (ví dụ, cửa sổ chính thu nhỏ tối đa rồi tối đa hóa)

Đây không phải là giải pháp tốt nhất. Tôi sẽ không đóng câu hỏi này với hy vọng rằng ai đó có thể giải thích tại sao WPF có chức năng này!

14

Đây là một tính năng không có giấy tờ WPF (Bug)

Lỗi này đã được báo cáo cho Microsoft hơn 7 năm về trước.

Modal dialog on top of non-modal window sends main window to back.

Đội WPF thời gian gần đây đã xem xét vấn đề này và sẽ không được giải quyết vấn đề này như vào thời điểm này nhóm nghiên cứu đang tập trung vào các lỗi ảnh hưởng đến số lượng cao nhất của các nhà phát triển WPF.

Hãy xem xét hành vi của tính năng không có giấy tờ này một chút.

Nó không Minimize, chỉ cần đi một cửa sổ đằng sau (trong chế độ gỡ lỗi, đằng sau cửa sổ visual studio)

bước để chứng minh:

  • Chạy ứng dụng này.

  • Giảm thiểu tất cả các cửa sổ khác (ví dụ: studio trực quan và tất cả các cửa sổ khác). Chỉ giữ ba cửa sổ này trên màn hình.

  • Đóng cả trẻ em, cha mẹ vẫn còn trong Normal Nhà nước

Kiểm tra mã này cho bằng chứng thêm: StateChange sẽ không cháy.

 protected override void OnStartup(StartupEventArgs e) 
     { 
      var parentWindow = new Window() { Title = "Parent" }; 
      parentWindow.StateChanged += (sender, ep)=> 
      { 
       var state = ((Window)sender).WindowState; 
      }; 
      parentWindow.Show(); 

      var childWindow1 = new Window { Owner = parentWindow, Title = "Child1" }; 
      childWindow1.Show(); 

      var childWindow2 = new Window { Owner = parentWindow, Title = "Child2" }; 
      childWindow2.Show(); 
     } 

Being topmost ngăn chặn điều này xảy ra

Nếu cửa sổ cha mẹ là trên cùng, điều này sẽ không xảy ra. Nhưng điều này có thể không phải là một lựa chọn trong nhiều trường hợp.

parentWindow.Topmost = true; 

Cách giải quyết

Kích hoạt phụ huynh trên gần child2.

childWindow2.Closed += (a, b) => { parentWindow.Activate(); }; 
+0

'chỉ cần đi một phía sau cửa sổ phòng thu trực quan'. đúng, nhưng không chỉ VS, nhưng cũng phía sau bất kỳ cửa sổ không được thu nhỏ nào khác, và không chỉ trong thời gian gỡ lỗi. – dovid

+0

@lomed: Đúng, nó chỉ đi một cửa sổ phía sau. – CharithJ

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