Làm thế nào để tạo hộp thoại phương thức trong WPF?


133

Tôi đang viết ứng dụng đầu tiên của mình trong WPF và muốn người dùng nhập một số dữ liệu trên cửa sổ hộp thoại phương thức. Rõ ràng, điều này không đơn giản để thực hiện trong WPF, vì cửa sổ cha mẹ vẫn được bật hoàn toàn và phương thức tạo cửa sổ con mới không dừng lại và chờ cửa sổ con gọi Đóng (). Thay vào đó nó chỉ tiếp tục tiến về phía trước. Đây không phải là điều tôi muốn.

Làm thế nào tôi có thể mở cửa sổ con và cửa sổ cha mẹ đợi con đóng trước khi cửa sổ cha mẹ tiếp tục thực thi?


Chia sẻ câu trả lời của tôi ở đây vì nó có thể giúp ai đó lang thang ở đây từ Google.
Shahin Dohan

Câu trả lời:


222

Bạn đã thử hiển thị cửa sổ của mình bằng phương thức ShowDialog chưa?

Đừng quên đặt thuộc tính Chủ sở hữu trên cửa sổ hộp thoại thành cửa sổ chính. Điều này sẽ tránh hành vi kỳ lạ khi Alt + Tabbing, v.v.


43

Rất nhiều câu trả lời này rất đơn giản và nếu ai đó đang bắt đầu WPF, họ có thể không biết tất cả "nội dung", vì nó phức tạp hơn là chỉ nói với ai đó "Sử dụng .ShowDialog()!". Nhưng đó là phương thức (không phải .Show()) mà bạn muốn sử dụng để chặn sử dụng cửa sổ bên dưới và để giữ cho mã tiếp tục cho đến khi cửa sổ phương thức được đóng lại.

Đầu tiên, bạn cần 2 cửa sổ WPF. (Người này sẽ gọi người kia.)

Từ cửa sổ đầu tiên, giả sử được gọi là MainWindow.xaml, trong mã phía sau của nó sẽ là:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}

Sau đó thêm nút của bạn vào XAML:

<Button Name="btnOpenModal" Click="btnOpenModal_Click" Content="Open Modal" />

Và nhấp chuột phải vào Clickthói quen, chọn "Chuyển đến định nghĩa". Nó sẽ tạo nó cho bạn trong MainWindow.xaml.cs:

private void btnOpenModal_Click(object sender, RoutedEventArgs e)
{
}

Trong chức năng đó, bạn phải chỉ định trang khác bằng lớp trang của nó. Giả sử bạn đặt tên trang đó là "ModalWindow", để nó trở thành lớp trang của nó và là cách bạn sẽ khởi tạo (gọi) nó:

private void btnOpenModal_Click(object sender, RoutedEventArgs e)
{
    ModalWindow modalWindow = new ModalWindow();
    modalWindow.ShowDialog();
}

Giả sử bạn có một giá trị bạn cần đặt trên hộp thoại phương thức. Tạo một hộp văn bản và một nút trong ModalWindowXAML:

<StackPanel Orientation="Horizontal">
    <TextBox Name="txtSomeBox" />
    <Button Name="btnSaveData" Click="btnSaveData_Click" Content="Save" /> 
</StackPanel>

Sau đó tạo lại một trình xử lý sự kiện (một Clicksự kiện khác ) và sử dụng nó để lưu giá trị hộp văn bản vào một biến tĩnh công khai ModalWindowvà gọi this.Close().

public partial class ModalWindow : Window
{
    public static string myValue = String.Empty;        
    public ModalWindow()
    {
        InitializeComponent();
    }

    private void btnSaveData_Click(object sender, RoutedEventArgs e)
    {
        myValue = txtSomeBox.Text;
        this.Close();
    }
}

Sau đó, sau .ShowDialog()tuyên bố của bạn , bạn có thể lấy giá trị đó và sử dụng nó:

private void btnOpenModal_Click(object sender, RoutedEventArgs e)
{
    ModalWindow modalWindow = new ModalWindow();
    modalWindow.ShowDialog();

    string valueFromModalTextBox = ModalWindow.myValue;
}

29

Window.Show Window sẽ hiển thị cửa sổ và tiếp tục thực hiện - đó là một cuộc gọi không chặn.

Window.ShowDialog sẽ chặn chuỗi cuộc gọi (kinda [1]) và hiển thị hộp thoại. Nó cũng sẽ chặn tương tác với cửa sổ cha / sở hữu. Khi hộp thoại bị loại bỏ (vì lý do gì) ShowDialog sẽ trở lại với người gọi và sẽ cho phép bạn truy cập DialogResult (nếu bạn muốn).

[1] Nó sẽ giữ cho bộ điều phối được bơm bằng cách đẩy khung bộ điều phối lên bộ nhúng của WPF. Điều này sẽ khiến bơm thông báo tiếp tục bơm.


giải thích chi tiết hơn xin vui lòng? Tôi đang xem xét một vấn đề tương tự khi tôi có một quá trình thử nghiệm đang chạy nhưng các thông báo cảnh báo có thể bật lên dưới dạng các hộp thoại phương thức nhưng tôi không muốn chặn thực thi.
Firoso

2

Đưa ra một đối tượng Window myWindow, myWindow.Show () sẽ mở nó một cách không điều độ và myWindow.ShowDialog () sẽ mở nó một cách điều độ. Tuy nhiên, ngay cả cái sau cũng không chặn, từ những gì tôi nhớ.


6
Tôi tin rằng nó chặn. Mã sau myWindow.Show () không thực thi cho đến sau khi myWindow gọi Đóng ().
Alex Baranosky

Cả bạn và @AlexBaranosky đều đúng: ShowDialogkhông quay lại cho đến khi phương thức được đóng lại, vì vậy nó sẽ chặn hoạt động điều phối hiện đang thực thi. Nhưng ShowDialogbản thân nó gọi một cách hiệu quả Dispatcher.Run(), vì vậy người điều phối tiếp tục thực hiện các hoạt động, có hiệu lực giữ cho UI đáp ứng.
Matt Thomas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.