ReactiveProperty와 Material Design In XAML Toolkit을 결합하여 응답을 기다리는 대화 상자 만들기
17071 단어 .NETReactivePropertyWPFXamlC#
개요
MVVM에서 넘어지는 포인트로서 자주 들 수 있는 것이, 다이얼로그 표시입니다.
단순히 대화 상자를 표시하고 OK를 누르면 닫는 내용을 이전에 썼습니다.
WPF로 갈 수있는 대화 상자를 내는 방법 - Qiita
이번에는 대화 상자가 닫힐 때까지 기다리고 결과를받는 방법
Material Design In XAML Toolkit 및 ReactiveProperty를 사용하여 설명하고 싶습니다.
또한 이번 내용은 현시점(2018/08/26)에서 최신 ReactiveProperty 5.2.0이 필요합니다.
설명
대화상자는 Material Design In XAML Toolkit의 DialogHost를 사용하여 표시됩니다.
DialogHost의 DialogContent 속성에 대화 상자의 View를 설정합니다.
대화 상자의 DataContext는 해당 대화 상자 VM을 설정합니다.
MainWindow.xaml(부분)<material:DialogHost.DialogContent>
<v:DialogWindow DataContext="{Binding DialogVM}" />
</material:DialogHost.DialogContent>
DialogHost의 IsOpen 속성을 변경하여 대화 상자를 표시하거나 숨깁니다.
그런 다음 IsOpen 속성을 대화 상자 VM의 IsOpen (ReactiveProperty)에 바인딩합니다.
MainWindow.xaml(부분)<material:DialogHost IsOpen="{Binding DialogVM.IsOpen.Value}">
MainWindowVM에서 대화 상자를 시작할 때 Bind 된 IsOpen에 true를 설정합니다.
그리고 즉시 IsOpen 변경 (= 대화 상자 종료)을 기다립니다.
MainWindowViewModel.cs(부분)DialogVM.IsOpen.Value = true;
await DialogVM.IsOpen;
대화 상자를 닫을 때
대화 상자 VM 내에서 IsOpen에 false를 설정합니다.
다이얼로그의 결과의 나방법은 여러가지 있습니다만, 이번은 다이얼로그 VM내의 ReactiveProperty로서 표현했습니다.
DialogWindowViewModel.cs (부분)IsOK.Value = true;
IsOpen.Value = false;
다이얼로그가 닫힌 후에는 MainWindowVM로 다이얼로그 VM의 다이얼로그 결과를 참조합니다.
MainWindowViewModel.cs(부분)DialogResultText.Value = DialogVM.IsOK.Value == true ? "おーけー" : "きゃんせる";
데모 프로그램 실행 결과
이번 데모 프로그램의 실행 결과입니다.
가운데 버튼을 누르면 대화상자가 나타납니다.

다이얼로그 안에는 조금 무서운 확인문과 OK와 Cancel의 2개의 버튼이 있습니다.
어느 쪽을 눌러도 대화 상자가 닫힙니다.

OK와 Cancel 중 어느 것을 눌렀는지에 따라 MainWindow의 문자가 바뀝니다.

전체 코드
데모 프로그램의 전체 코드입니다.
보기
MainWindow.xaml<Window
x:Class="ResponseDialogTest.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:v="clr-namespace:ResponseDialogTest.Views"
xmlns:vm="clr-namespace:ResponseDialogTest.ViewModels"
Width="400"
Height="350">
<Window.DataContext>
<vm:MainWindowViewModel />
</Window.DataContext>
<!-- DialogHostのIsOpenプロパティをDialogVMのIsOpenプロパティにBindしている -->
<material:DialogHost IsOpen="{Binding DialogVM.IsOpen.Value}">
<material:DialogHost.DialogContent>
<v:DialogWindow DataContext="{Binding DialogVM}" />
</material:DialogHost.DialogContent>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="18" Text="ダイアログ結果:" />
<TextBlock FontSize="18" Text="{Binding DialogResultText.Value}" />
</StackPanel>
<Button Command="{Binding StartDialogCommand}" Content="ダイアログ開始" />
</StackPanel>
</material:DialogHost>
</Window>
DialogWindow.xaml<UserControl
x:Class="ResponseDialogTest.Views.DialogWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<Style BasedOn="{StaticResource MaterialDesignFlatButton}" TargetType="{x:Type Button}">
<Setter Property="Margin" Value="10" />
<Setter Property="Width" Value="150" />
</Style>
</UserControl.Resources>
<StackPanel>
<TextBlock
Margin="15"
HorizontalAlignment="Center"
FontSize="24"
Text="ほんとうに実行しますか?" />
<StackPanel Orientation="Horizontal">
<Button Command="{Binding OkCommand}" Content="OK" />
<Button Command="{Binding CancelCommand}" Content="Cancel" />
</StackPanel>
</StackPanel>
</UserControl>
ViewModel
MainWindowViewModel.cspublic class MainWindowViewModel : ViewModel
{
/// <summary>
/// ダイアログ処理実行コマンド
/// </summary>
public AsyncReactiveCommand StartDialogCommand { get; } = new AsyncReactiveCommand();
/// <summary>
/// ダイアログ内容ViewModel
/// </summary>
public DialogWindowViewModel DialogVM { get; } = new DialogWindowViewModel();
/// <summary>
/// ダイアログ結果文字列
/// </summary>
public ReactiveProperty<string> DialogResultText { get; } = new ReactiveProperty<string>();
public MainWindowViewModel()
{
StartDialogCommand.Subscribe(StartDialog);
}
private async Task StartDialog()
{
//ダイアログ内容VMのOpenプロパティを変更することで、ダイアログのOpen・Closeを制御する
DialogVM.IsOpen.Value = true;
//ダイアログのOpenプロパティが変更されるのを待つ
await DialogVM.IsOpen;
//ダイアログ結果を文字列に加工して表示
DialogResultText.Value = DialogVM.IsOK.Value == true ? "おーけー" : "きゃんせる";
}
}
DialogWindowViewModel.cspublic class DialogWindowViewModel
{
/// <summary>
/// ダイアログのOpen状態
/// </summary>
public ReactiveProperty<bool> IsOpen { get; } = new ReactiveProperty<bool>(initialValue: false);
/// <summary>
/// ダイアログ結果(初期状態はNull)
/// </summary>
public ReactiveProperty<bool?> IsOK { get; } = new ReactiveProperty<bool?>(initialValue: null);
public ReactiveCommand OkCommand { get; } = new ReactiveCommand();
public ReactiveCommand CancelCommand { get; } = new ReactiveCommand();
public DialogWindowViewModel()
{
//ダイアログが開いたときにダイアログ結果をNullに設定
IsOpen
.Where(x => x)
.Subscribe(_ =>
IsOK.Value = null);
OkCommand.Subscribe(() =>
{
IsOK.Value = true;
IsOpen.Value = false;
});
CancelCommand.Subscribe(() =>
{
IsOK.Value = false;
IsOpen.Value = false;
});
}
}
환경
VisualStudio2017
.NET Framework 4.7.1
C#7.1
ReactiveProperty 5.2.0
MaterialDesignThemes 2.4.1.1101
Reference
이 문제에 관하여(ReactiveProperty와 Material Design In XAML Toolkit을 결합하여 응답을 기다리는 대화 상자 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/soi/items/91117d32035b796a24da
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
대화상자는 Material Design In XAML Toolkit의 DialogHost를 사용하여 표시됩니다.
DialogHost의 DialogContent 속성에 대화 상자의 View를 설정합니다.
대화 상자의 DataContext는 해당 대화 상자 VM을 설정합니다.
MainWindow.xaml(부분)
<material:DialogHost.DialogContent>
<v:DialogWindow DataContext="{Binding DialogVM}" />
</material:DialogHost.DialogContent>
DialogHost의 IsOpen 속성을 변경하여 대화 상자를 표시하거나 숨깁니다.
그런 다음 IsOpen 속성을 대화 상자 VM의 IsOpen (ReactiveProperty)에 바인딩합니다.
MainWindow.xaml(부분)
<material:DialogHost IsOpen="{Binding DialogVM.IsOpen.Value}">
MainWindowVM에서 대화 상자를 시작할 때 Bind 된 IsOpen에 true를 설정합니다.
그리고 즉시 IsOpen 변경 (= 대화 상자 종료)을 기다립니다.
MainWindowViewModel.cs(부분)
DialogVM.IsOpen.Value = true;
await DialogVM.IsOpen;
대화 상자를 닫을 때
대화 상자 VM 내에서 IsOpen에 false를 설정합니다.
다이얼로그의 결과의 나방법은 여러가지 있습니다만, 이번은 다이얼로그 VM내의 ReactiveProperty로서 표현했습니다.
DialogWindowViewModel.cs (부분)
IsOK.Value = true;
IsOpen.Value = false;
다이얼로그가 닫힌 후에는 MainWindowVM로 다이얼로그 VM의 다이얼로그 결과를 참조합니다.
MainWindowViewModel.cs(부분)
DialogResultText.Value = DialogVM.IsOK.Value == true ? "おーけー" : "きゃんせる";
데모 프로그램 실행 결과
이번 데모 프로그램의 실행 결과입니다.
가운데 버튼을 누르면 대화상자가 나타납니다.

다이얼로그 안에는 조금 무서운 확인문과 OK와 Cancel의 2개의 버튼이 있습니다.
어느 쪽을 눌러도 대화 상자가 닫힙니다.

OK와 Cancel 중 어느 것을 눌렀는지에 따라 MainWindow의 문자가 바뀝니다.

전체 코드
데모 프로그램의 전체 코드입니다.
보기
MainWindow.xaml<Window
x:Class="ResponseDialogTest.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:v="clr-namespace:ResponseDialogTest.Views"
xmlns:vm="clr-namespace:ResponseDialogTest.ViewModels"
Width="400"
Height="350">
<Window.DataContext>
<vm:MainWindowViewModel />
</Window.DataContext>
<!-- DialogHostのIsOpenプロパティをDialogVMのIsOpenプロパティにBindしている -->
<material:DialogHost IsOpen="{Binding DialogVM.IsOpen.Value}">
<material:DialogHost.DialogContent>
<v:DialogWindow DataContext="{Binding DialogVM}" />
</material:DialogHost.DialogContent>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="18" Text="ダイアログ結果:" />
<TextBlock FontSize="18" Text="{Binding DialogResultText.Value}" />
</StackPanel>
<Button Command="{Binding StartDialogCommand}" Content="ダイアログ開始" />
</StackPanel>
</material:DialogHost>
</Window>
DialogWindow.xaml<UserControl
x:Class="ResponseDialogTest.Views.DialogWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<Style BasedOn="{StaticResource MaterialDesignFlatButton}" TargetType="{x:Type Button}">
<Setter Property="Margin" Value="10" />
<Setter Property="Width" Value="150" />
</Style>
</UserControl.Resources>
<StackPanel>
<TextBlock
Margin="15"
HorizontalAlignment="Center"
FontSize="24"
Text="ほんとうに実行しますか?" />
<StackPanel Orientation="Horizontal">
<Button Command="{Binding OkCommand}" Content="OK" />
<Button Command="{Binding CancelCommand}" Content="Cancel" />
</StackPanel>
</StackPanel>
</UserControl>
ViewModel
MainWindowViewModel.cspublic class MainWindowViewModel : ViewModel
{
/// <summary>
/// ダイアログ処理実行コマンド
/// </summary>
public AsyncReactiveCommand StartDialogCommand { get; } = new AsyncReactiveCommand();
/// <summary>
/// ダイアログ内容ViewModel
/// </summary>
public DialogWindowViewModel DialogVM { get; } = new DialogWindowViewModel();
/// <summary>
/// ダイアログ結果文字列
/// </summary>
public ReactiveProperty<string> DialogResultText { get; } = new ReactiveProperty<string>();
public MainWindowViewModel()
{
StartDialogCommand.Subscribe(StartDialog);
}
private async Task StartDialog()
{
//ダイアログ内容VMのOpenプロパティを変更することで、ダイアログのOpen・Closeを制御する
DialogVM.IsOpen.Value = true;
//ダイアログのOpenプロパティが変更されるのを待つ
await DialogVM.IsOpen;
//ダイアログ結果を文字列に加工して表示
DialogResultText.Value = DialogVM.IsOK.Value == true ? "おーけー" : "きゃんせる";
}
}
DialogWindowViewModel.cspublic class DialogWindowViewModel
{
/// <summary>
/// ダイアログのOpen状態
/// </summary>
public ReactiveProperty<bool> IsOpen { get; } = new ReactiveProperty<bool>(initialValue: false);
/// <summary>
/// ダイアログ結果(初期状態はNull)
/// </summary>
public ReactiveProperty<bool?> IsOK { get; } = new ReactiveProperty<bool?>(initialValue: null);
public ReactiveCommand OkCommand { get; } = new ReactiveCommand();
public ReactiveCommand CancelCommand { get; } = new ReactiveCommand();
public DialogWindowViewModel()
{
//ダイアログが開いたときにダイアログ結果をNullに設定
IsOpen
.Where(x => x)
.Subscribe(_ =>
IsOK.Value = null);
OkCommand.Subscribe(() =>
{
IsOK.Value = true;
IsOpen.Value = false;
});
CancelCommand.Subscribe(() =>
{
IsOK.Value = false;
IsOpen.Value = false;
});
}
}
환경
VisualStudio2017
.NET Framework 4.7.1
C#7.1
ReactiveProperty 5.2.0
MaterialDesignThemes 2.4.1.1101
Reference
이 문제에 관하여(ReactiveProperty와 Material Design In XAML Toolkit을 결합하여 응답을 기다리는 대화 상자 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/soi/items/91117d32035b796a24da
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
데모 프로그램의 전체 코드입니다.
보기
MainWindow.xaml
<Window
x:Class="ResponseDialogTest.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:v="clr-namespace:ResponseDialogTest.Views"
xmlns:vm="clr-namespace:ResponseDialogTest.ViewModels"
Width="400"
Height="350">
<Window.DataContext>
<vm:MainWindowViewModel />
</Window.DataContext>
<!-- DialogHostのIsOpenプロパティをDialogVMのIsOpenプロパティにBindしている -->
<material:DialogHost IsOpen="{Binding DialogVM.IsOpen.Value}">
<material:DialogHost.DialogContent>
<v:DialogWindow DataContext="{Binding DialogVM}" />
</material:DialogHost.DialogContent>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="18" Text="ダイアログ結果:" />
<TextBlock FontSize="18" Text="{Binding DialogResultText.Value}" />
</StackPanel>
<Button Command="{Binding StartDialogCommand}" Content="ダイアログ開始" />
</StackPanel>
</material:DialogHost>
</Window>
DialogWindow.xaml
<UserControl
x:Class="ResponseDialogTest.Views.DialogWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<Style BasedOn="{StaticResource MaterialDesignFlatButton}" TargetType="{x:Type Button}">
<Setter Property="Margin" Value="10" />
<Setter Property="Width" Value="150" />
</Style>
</UserControl.Resources>
<StackPanel>
<TextBlock
Margin="15"
HorizontalAlignment="Center"
FontSize="24"
Text="ほんとうに実行しますか?" />
<StackPanel Orientation="Horizontal">
<Button Command="{Binding OkCommand}" Content="OK" />
<Button Command="{Binding CancelCommand}" Content="Cancel" />
</StackPanel>
</StackPanel>
</UserControl>
ViewModel
MainWindowViewModel.cs
public class MainWindowViewModel : ViewModel
{
/// <summary>
/// ダイアログ処理実行コマンド
/// </summary>
public AsyncReactiveCommand StartDialogCommand { get; } = new AsyncReactiveCommand();
/// <summary>
/// ダイアログ内容ViewModel
/// </summary>
public DialogWindowViewModel DialogVM { get; } = new DialogWindowViewModel();
/// <summary>
/// ダイアログ結果文字列
/// </summary>
public ReactiveProperty<string> DialogResultText { get; } = new ReactiveProperty<string>();
public MainWindowViewModel()
{
StartDialogCommand.Subscribe(StartDialog);
}
private async Task StartDialog()
{
//ダイアログ内容VMのOpenプロパティを変更することで、ダイアログのOpen・Closeを制御する
DialogVM.IsOpen.Value = true;
//ダイアログのOpenプロパティが変更されるのを待つ
await DialogVM.IsOpen;
//ダイアログ結果を文字列に加工して表示
DialogResultText.Value = DialogVM.IsOK.Value == true ? "おーけー" : "きゃんせる";
}
}
DialogWindowViewModel.cs
public class DialogWindowViewModel
{
/// <summary>
/// ダイアログのOpen状態
/// </summary>
public ReactiveProperty<bool> IsOpen { get; } = new ReactiveProperty<bool>(initialValue: false);
/// <summary>
/// ダイアログ結果(初期状態はNull)
/// </summary>
public ReactiveProperty<bool?> IsOK { get; } = new ReactiveProperty<bool?>(initialValue: null);
public ReactiveCommand OkCommand { get; } = new ReactiveCommand();
public ReactiveCommand CancelCommand { get; } = new ReactiveCommand();
public DialogWindowViewModel()
{
//ダイアログが開いたときにダイアログ結果をNullに設定
IsOpen
.Where(x => x)
.Subscribe(_ =>
IsOK.Value = null);
OkCommand.Subscribe(() =>
{
IsOK.Value = true;
IsOpen.Value = false;
});
CancelCommand.Subscribe(() =>
{
IsOK.Value = false;
IsOpen.Value = false;
});
}
}
환경
VisualStudio2017
.NET Framework 4.7.1
C#7.1
ReactiveProperty 5.2.0
MaterialDesignThemes 2.4.1.1101
Reference
이 문제에 관하여(ReactiveProperty와 Material Design In XAML Toolkit을 결합하여 응답을 기다리는 대화 상자 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/soi/items/91117d32035b796a24da
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(ReactiveProperty와 Material Design In XAML Toolkit을 결합하여 응답을 기다리는 대화 상자 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/soi/items/91117d32035b796a24da텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)