WPF에서 모달 대화 상자를 만드는 방법은 무엇입니까?


133

WPF에서 첫 번째 응용 프로그램을 작성 중이며 사용자가 모달 대화 상자 창에 일부 데이터를 입력하도록하고 싶습니다. 부모 창은 완전히 활성화되어 있고 새 자식 창을 만든 메서드가 중지되지 않고 자식 창이 Close ()를 호출 할 때까지 기다리기 때문에 WPF에서는이 작업이 간단하지 않습니다. 대신 계속 진행됩니다. 이것은 내가 원하는 것이 아닙니다.

자식 창이 열리고 부모 창이 계속 실행되기 전에 자식 창이 닫힐 때까지 기다리는 방법은 무엇입니까?


여기에서 내 답변을 공유 하면 누군가 Google에서 방황하는 데 도움이 될 수 있습니다.
Shahin Dohan

답변:



43

이러한 많은 답변은 단순하며 누군가 WPF를 시작하는 경우 누군가에게 "Use .ShowDialog()!"를 말하는 것보다 더 복잡하기 때문에 모든 "들어간 (in-and-out)"을 알지 못할 수 있습니다 . 그러나 이것이 .Show()기본 윈도우의 사용을 차단하고 모달 윈도우가 닫힐 때까지 코드가 계속되는 것을 막기 위해 사용하려는 방법 (아닌 )입니다.

먼저 2 개의 WPF 창이 필요합니다. (하나는 다른 사람에게 전화 할 것입니다.)

첫 번째 창에서 MainWindow.xaml이라는 코드 숨김은 다음과 같습니다.

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

그런 다음 XAML에 버튼을 추가하십시오.

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

Click루틴을 마우스 오른쪽 단추로 클릭하고 "정의로 이동"을 선택하십시오. MainWindow.xaml.cs에 생성됩니다.

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

해당 함수 내에서 페이지 클래스를 사용하여 다른 페이지를 지정해야합니다. 다른 페이지의 이름을 "ModalWindow"라고 지정하면 페이지 클래스가되고이를 인스턴스화 (호출)하는 방법입니다.

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

모달 대화 상자에서 설정해야 할 값이 있다고 가정하십시오. ModalWindowXAML 에서 텍스트 상자와 버튼을 만듭니다 .

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

그런 다음 이벤트 핸들러 (다른 Click이벤트)를 다시 작성하고이를 사용하여 텍스트 상자 값을 공용 정적 변수 on에 저장 ModalWindow하고 호출하십시오 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();
    }
}

그런 다음 .ShowDialog()진술 후에 그 가치를 파악하여 사용할 수 있습니다.

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

    string valueFromModalTextBox = ModalWindow.myValue;
}

29

Window.Show Window는 창을 표시하고 실행을 계속합니다-차단되지 않은 호출입니다.

Window.ShowDialog는 호출 스레드 (kinda [1])를 차단하고 대화 상자를 표시합니다. 또한 부모 / 소유 창과의 상호 작용을 차단합니다. 어떤 이유로 든 대화 상자가 닫히면 ShowDialog가 호출자에게 돌아가고 DialogResult에 액세스 할 수 있습니다 (원하는 경우).

[1] 디스패처 프레임을 WPF 디패 처로 밀어 디스패처 펌핑을 유지합니다. 이로 인해 메시지 펌프가 계속 펌핑됩니다.


좀 더 자세히 설명해주세요. 테스트 프로세스를 실행하는 비슷한 문제를보고 있지만 경고 메시지가 모달 대화 상자로 나타날 수 있지만 실행을 차단하고 싶지 않습니다.
Firoso

2

Window 객체 myWindow가 주어지면 myWindow.Show ()는 모달리스로 열리고 myWindow.ShowDialog ()는 모달로 열립니다. 그러나 후자조차도 내가 기억하는 것을 차단하지 않습니다.


6
나는 그것이 차단한다고 생각합니다. myWindow.Show () 이후의 코드는 myWindow가 Close ()를 호출 할 때까지 실행되지 않습니다.
Alex Baranosky

귀하와 @AlexBaranosky는 모두 정확합니다. ShowDialog모달이 닫힐 때까지 반환되지 않으므로 현재 실행중인 발송자 작업을 차단합니다. 그러나 ShowDialog자체적으로 효과적으로 호출 Dispatcher.Run()하므로 디스패처는 작업을 계속 실행하여 사실상 UI 응답 성을 유지합니다.
매트 토마스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.