2009-10-08 41 views
37

Cách người ta có thể hiển thị cửa sổ hộp thoại (ví dụ: đăng nhập/tùy chọn, vv) trước cửa sổ chính?WPF hiển thị hộp thoại trước cửa sổ chính

Đây là những gì tôi đã cố gắng (nó rõ ràng has once worked, nhưng không được nữa):

XAML:

<Application ... 
    Startup="Application_Startup"> 

Application:

public partial class App : Application 
{ 
    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     Window1 myMainWindow = new Window1(); 
     DialogWindow myDialogWindow = new DialogWindow(); 
     myDialogWindow.ShowDialog(); 
    } 
} 

Kết quả: myDialogWindow được hiển thị fi rst. Khi nó được đóng lại, Window1 được hiển thị như mong đợi. Nhưng khi tôi đóng Window1, ứng dụng không đóng lại.

Trả lời

67

Đây là giải pháp đầy đủ mà làm việc cho tôi:

Trong App.xaml, tôi loại bỏ những thứ StartupUri, và thêm một Startup handler:

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

In App.xaml.cs, tôi xác định xử lý như sau:

public partial class App 
{ 
    private void ApplicationStart(object sender, StartupEventArgs e) 
    { 
     //Disable shutdown when the dialog closes 
     Current.ShutdownMode = ShutdownMode.OnExplicitShutdown; 

     var dialog = new DialogWindow(); 

     if (dialog.ShowDialog() == true) 
     { 
      var mainWindow = new MainWindow(dialog.Data); 
      //Re-enable normal shutdown mode. 
      Current.ShutdownMode = ShutdownMode.OnMainWindowClose; 
      Current.MainWindow = mainWindow; 
      mainWindow.Show(); 
     } 
     else 
     { 
      MessageBox.Show("Unable to load data.", "Error", MessageBoxButton.OK); 
      Current.Shutdown(-1); 
     } 
    } 
} 
+1

Không cần thiết phải xóa StartupUri để đạt được kết quả tương tự. Bit quan trọng là thay đổi chế độ tắt trước hộp thoại, sau đó thay đổi lại sau hộp thoại. Nơi mà chúng ta có thể nhắm đến việc sử dụng mã phía sau để tăng thêm nhà thiết kế chỉ khi nó quá phức tạp hoặc không hiệu quả để thể hiện trong xaml. Trong trường hợp này, một thuộc tính trong Xaml mà tất cả chúng ta mong đợi đều tốt hơn 2 dòng ẩn bên trong logic điều kiện. –

2

Vì vậy, bạn muốn hiển thị một cửa sổ, một cửa sổ khác, nhưng đóng ứng dụng khi cửa sổ đó bị đóng? Bạn có thể cần phải thiết lập các ShutdownMode để OnMainWindowClose và thiết lập MainWindow để Window1, dọc theo dòng ok:

Window1 myMainWindow = new Window1(); 
Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose; 
Application.Current.MainWindow = myMainWindow; 
DialogWindow myDialogWindow = new DialogWindow(); 
myDialogWindow.ShowDialog(); 
+0

Bạn có thể dán toàn bộ lớp ứng dụng không? (Điều đó đã không làm việc (ứng dụng không bao giờ đóng), cũng không phải phiên bản sửa đổi tôi đã thử) Ngoài ra nếu bạn nhìn vào liên kết tôi dán, nó nói MainWindow được thiết lập ... – Ciantic

+0

Gỡ lỗi dễ dàng xác nhận MainWindow, và bất cứ điều gì tôi đặt trong ShutdownMode không quan trọng. – Ciantic

0

đây, làm điều đó như thế này. điều này sẽ actaully thay đổi cửa sổ chính của bạn và sẽ làm việc đúng w/o phải thay đổi cài đặt của đối tượng ứng dụng của bạn.

đảm bảo xóa trình xử lý sự kiện để khởi động ứng dụng và đặt StartupUri trong tệp app.xaml của bạn.

public partial class App : Application 
{ 
    bool init = false; 
    protected override void OnActivated(EventArgs e) 
    { 
     base.OnActivated(e); 
     if (!init) 
     { 
     this.MainWindow.Closing += new System.ComponentModel.CancelEventHandler(MainWindow_Closing); 
     init = true; 
     } 
    } 

    void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
    { 
     Window toClose = this.MainWindow; 
     this.MainWindow = new Window2(); 
     this.MainWindow.Show(); 
    } 
} 
+0

Tôi sẽ thử, nhưng bạn nhận ra rằng, đây không phải là cách "đúng" để làm điều đó. Phải có một số cách tốt để làm điều này. Mỗi nơi tôi tìm kiếm OnStartup là dân cư hoặc ghi đè ... nó thậm chí còn nhận được các đối số dòng lệnh. Ngoài ra, tôi đã cố gắng để tạo ra "Run" chức năng lớp ứng dụng của tôi, và nếu tôi làm như vậy, không có gì xuất hiện trừ khi tôi đặt base.Run (...). Vì vậy, đó có thể là một cái gì đó để chăm sóc. – Ciantic

+0

bạn vẫn có thể ghi đè OnStartup để xử lý thời gian chạy của bạn và như vậy. tại sao đây không phải là cách "đúng" để làm điều đó? điều này hoạt động tuyệt vời. –

+0

Nó không phải là thanh lịch, điều này * nên * được dễ dàng. Như nó đã được, nhưng xin lỗi bạn cũng có, tôi sai lầm với câu hỏi của tôi "..." trong thẻ ứng dụng là quá nhiều. – Ciantic

6

xin lỗi rồi, đây là giải pháp:

câu hỏi ban đầu của tôi đã làm việc gần như, chỉ có một điều để thêm, loại bỏ các StartupUri từ ứng dụng XAML và sau đó thêm các Show để cửa sổ chính.

Đó là:

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

Ở trên, StartupUri loại bỏ.

Thêm myMainWindow.Show() quá:

public partial class App : Application 
{ 

    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     Window1 myMainWindow = new Window1(); 
     DialogWindow myDialogWindow = new DialogWindow(); 
     myDialogWindow.ShowDialog(); 
     myMainWindow.Show(); 
    } 

} 
+2

Điều này không hiệu quả đối với tôi, việc tắt ứng dụng sau khi DialogWindow bị đóng. – Gleno

+0

Không hoạt động cho tôi - OK = Chính hiển thị tốt. Hủy = treo, tức là không đóng. Câu trả lời cần làm lại. – Bertie

3

WPF đặt App.Current.MainWindow vào cửa sổ đầu tiên mở ra. Nếu bạn có quyền kiểm soát đối với hàm tạo cửa sổ phụ, chỉ cần đặt App.Current.MainWindow = Null tại đó. Khi cửa sổ chính của bạn được xây dựng, cửa sổ chính sẽ được gán cho thuộc tính App.Current.MainWindow như mong đợi mà không có bất kỳ sự can thiệp nào.

public partial class TraceWindow : Window 
{ 
    public TraceWindow() 
    { 
     InitializeComponent(); 
     if (App.Current.MainWindow == this) 
     { 
      App.Current.MainWindow = null; 
     } 
    } 
} 

Nếu bạn không có quyền truy cập, bạn vẫn có thể đặt MainWindow trong hàm tạo của cửa sổ chính.

3

Nếu bạn đặt Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown; vào constructor của hộp thoại, và thêm

protected override void OnClosed(EventArgs e) { 
    base.OnClosed(e); 
    Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose; 
} 

vào lớp hộp thoại, bạn không cần phải lo lắng về việc thực hiện bất kỳ thay đổi đối với hành vi mặc định của ứng dụng. Điều này làm việc tuyệt vời nếu bạn muốn chỉ cần chụp một màn hình đăng nhập vào một ứng dụng đã tồn tại mà không cần tinh chỉnh các thủ tục khởi động.

+0

Không nghi ngờ gì là giải pháp dễ triển khai nhất. Nó có thể không phải là mvvm thuần túy (tức là hoàn toàn không có mã trong mã phía sau) nhưng tôi không nghĩ rằng việc thêm chút ít này sẽ tạo ra nhiều nếu có sự khác biệt và ít nhất cũng có lợi thế lớn để trang bị thêm. –

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