[英]How to add a yes-no confirmation dialog in a WPF MVVM application?
I am developping a .net desktop WPF app in MVVM pattern using Visual Studio.我正在使用 Visual Studio 以 MVVM 模式开发一个 .net 桌面 WPF 应用程序。 I want to add confirmation dialog and bind "yes" or "no" according to the user click.
我想添加确认对话框并根据用户点击绑定“是”或“否”。 I made some research but solutions offered either is not appropriate for MVVM pattern or requires adding a lot of external packages which I dont want to.
我做了一些研究,但提供的解决方案要么不适合 MVVM 模式,要么需要添加很多我不想添加的外部包。 Could anyone help me to find a proper solution that solves my problem?
谁能帮我找到解决我问题的合适解决方案?
I would like to suggest a solution that is MVVM oriented.我想建议一个面向 MVVM 的解决方案。 One way to judge if we have an MVVM solution is if we can plan a unit test.
判断我们是否有 MVVM 解决方案的一种方法是我们是否可以计划单元测试。 In this regard we would like to build a view model that is not attempting to raise a dialog and is just setting properties.
在这方面,我们想构建一个视图 model,它不会尝试引发对话框,而只是设置属性。 I use a Popup that we bind to the view model.
我使用我们绑定到视图 model 的弹出窗口。
The view model will look as following:视图 model 将如下所示:
public class MainViewModel:Binding
{
bool _isQuestionRaised;
public bool IsQuestionRaised
{
get { return _isQuestionRaised; }
set { _isQuestionRaised = value; NotifyPropertyChanged(nameof(IsQuestionRaised)); }
}
bool _yes;
public bool Yes
{
get { return _yes; }
set {
_yes = value;
NotifyPropertyChanged(nameof(Yes));
if (_yes) DoYesThings();
}
}
bool _no;
public bool No
{
get { return _no; }
set {
_no = value;
NotifyPropertyChanged(nameof(No));
if (_no) DoNoThings();
}
}
public void DoYesThings()
{
IsQuestionRaised = false;
}
public void DoNoThings()
{
IsQuestionRaised = false;
}
public void QuestionIsRaised()
{
IsQuestionRaised = true;
}
public void QuestionIsDismissed()
{
IsQuestionRaised = false;
}
}
The XAML code: XAML代码:
<Grid>
<Grid.Resources>
<Style x:Key="btnStyle" TargetType="Button">
<Setter Property="Height" Value="20"/>
<Setter Property="Width" Value="40"/>
<Setter Property="Margin" Value="10,10,10,10"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Click="Button_Click">Raise A Question</Button>
<Popup IsOpen="{Binding IsQuestionRaised}" Width="300" Height="100" Placement="Center" >
<Border BorderThickness="3">
<StackPanel Background="Aqua" Orientation="Vertical">
<TextBlock Margin="20,0,0,20">Yes or No ?</TextBlock>
<StackPanel Orientation="Horizontal">
<Button Click="Button_Click_Yes" Style="{StaticResource btnStyle}">Yes</Button>
<Button Click="Button_Click_No" Style="{StaticResource btnStyle}">No</Button>
<Button Click="Button_Click_Close" Style="{StaticResource btnStyle}">Close</Button>
</StackPanel>
</StackPanel>
</Border>
</Popup>
</Grid>
I use here code behind but we can definitely use delegate command in the ViewModel instead.我在这里使用代码隐藏,但我们绝对可以在 ViewModel 中使用委托命令。
public partial class MainWindow : Window
{
MainViewModel _mainViewModel = new MainViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = _mainViewModel;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
_mainViewModel.QuestionIsRaised();
}
private void Button_Click_Yes(object sender, RoutedEventArgs e)
{
_mainViewModel.Yes = true;
}
private void Button_Click_No(object sender, RoutedEventArgs e)
{
_mainViewModel.No = true;
}
private void Button_Click_Close(object sender, RoutedEventArgs e)
{
_mainViewModel.QuestionIsDismissed();
}
}
I would recommend you to make a Window with its own Viewmodel and View.我建议您使用自己的 Viewmodel 和 View 制作一个 Window。 Like this: Add a new Window.
像这样:添加一个新的 Window。
DialogWindow.xaml DialogWindow.xaml
<Window x:Class="ComboBoxItemPanel_Testing.Dialog_Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ComboBoxItemPanel_Testing"
mc:Ignorable="d"
Title="Dialog_Window" Height="150" Width="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock Text="Give me a number!"/>
<TextBox Text="{Binding Path=MyNumber}"/>
</StackPanel>
<StackPanel Orientation="Horizontal"
Grid.Row="1"
HorizontalAlignment="Center">
<Button Content="Yes"
Click="Yes_Button"
Margin="10"/>
<Button Content="No"
Margin="10"
Click="No_Button"/>
</StackPanel>
</Grid>
DialogWinodw.xaml.cs DialogWinodw.xaml.cs
using System.Windows;
namespace ComboBoxItemPanel_Testing
{
/// <summary>
/// Interaction logic for Dialog_Window.xaml
/// </summary>
public partial class Dialog_Window : Window
{
public Dialog_Window(object datacontext)
{
InitializeComponent();
DataContext = datacontext;
}
private void Yes_Button(object sender, RoutedEventArgs e)
{
DialogResult = true;
}
private void No_Button(object sender, RoutedEventArgs e)
{
DialogResult = false;
}
}
}
Add a new class to define your ViewModel.添加一个新的 class 来定义您的 ViewModel。 DialogWindowViewModel.cs
DialogWindowViewModel.cs
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace ComboBoxItemPanel_Testing
{
public class DialogWindowViewModel : INotifyPropertyChanged
{
private int _myNumber;
public int MyNumber
{
get => _myNumber;
set
{
if (_myNumber != value)
{
_myNumber = value;
}
}
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
try
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
catch (Exception ex)
{
Console.WriteLine($"PropertyChanged event handler FAILED : {ex.Message}");
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
And u can use this like this:你可以这样使用它:
DialogWindowViewModel vm = new DialogWindowViewModel();
Dialog_Window dialog = new Dialog_Window(vm);
if (dialog.ShowDialog().Value)
{
//Clicked Yes button
//use ur viewModel
Console.WriteLine("Selected number: " + vm.MyNumber);
}
else
{
//Clicked No Button
Console.WriteLine("You didnt selected a number!");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.