Подтвердить что ты не робот

Ok отменить Диалог MVVM Pattern wpf. Как я могу это сделать

Я работаю над приложением MVVM wpf, и мне нужно показать различные диалоги с отменой ok. Я видел несколько в сети, но внешний вид слишком сложный или, возможно, его борьба.

Я заметил, что многие, которые используют "IDialogService"

Может ли кто-нибудь указать мне ссылку или есть фрагмент, удобный для того, как реализовать диалог с использованием шаблона MVVM?

Большое спасибо

4b9b3361

Ответ 1

здесь находится диалог barebones с кнопками OK и Cancel. Я включил XAML, View и ViewModel:

XAML:

<Window
    x:Class="TestProject.Views.OKCancelDialog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
    Title="Window Title"
    Height="300"
    Width="600"
    WindowStartupLocation="CenterOwner"
    WindowStyle="ToolWindow"
    ResizeMode="CanResize"
    UseLayoutRounding="True"
    TextOptions.TextFormattingMode="Display">

    <Grid>
        <Button
            Name="OKButton"
            Content="OK"
            Height="23"
            HorizontalAlignment="Right" 
            Margin="0,0,93,12"
            VerticalAlignment="Bottom" 
            Width="75" 
            Click="OKButton_Click"
            IsDefault="True"
            Command="{Binding OKButtonCommand}" />

        <Button
            Name="CancelButton"
            Content="Cancel" 
            Height="23" 
            HorizontalAlignment="Right" 
            Margin="0,0,12,12"
            VerticalAlignment="Bottom"
            Width="75" 
            IsCancel="True" />
    </Grid>
</Window>

Codebehind:

using System.Windows;
using TestProject.ViewModel;

namespace TestProject.Views
{
    public partial class OKCancelDialog : Window
    {
        private readonly OKCancelViewModel viewModel;

        //I use DI to inject the ViewModel into the View
        //This will allow you to use the view for different ViewModels if you need to.
        //Create an Interface for your ViewModel to implement to make ViewModel unit testing
        //easier. Testing frameworks such as rhino mock require Interfaces to test methods
        //in a class under test and it allows you to use an IoC Container to create the
        //ViewModel for you.                 
        public OpenReturnDialog(IOKCancelViewModel viewModel)
        {
            InitializeComponent();
            this.viewModel = viewModel; //Do this if you need access to the VM from inside your View. Or you could just use this.Datacontext to access the VM.
            this.DataContext = viewModel;
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = true;
        }

    }
}

ViewModel

using Microsoft.Practices.Composite.Presentation.Commands;


namespace TestProject.ViewModel
{
    public class OKCancelViewModel
    {
        public OKCancelViewModel()
        {
            OKButtonCommand = new DelegateCommand<object>(HandleOKButtonCommand, CanExecuteOKButtonCommand);
        }

        public DelegateCommand<object> OKButtonCommand { get; private set; }

        public void HandleOKButtonCommand(object obj)
        {
             //Here is where your code for OK button clicks go.

        }

        public bool CanExecuteOKButtonCommand(object obj)
        {
            //Put code to determine when the OK button will be enabled/disabled.
        } 

        //You may want to add a command for the Cancel button also if you have a need to 
        //enable/disable the cancel button
        //The command will look just like the OK button command above.
    }
}

Теперь вы, скорее всего, захотите, чтобы ваша ViewModel реализовала INotifyPropertyChanged в том случае, если у вас есть другие элементы управления в пользовательском интерфейсе, которые будут привязываться к свойствам в ViewModel.

Надеюсь, что это поможет...

Ответ 2

Я думаю, что все остальные, которые используют IDialogService или фактически создают свои собственные диалоги, перерабатывают проблему. Мне очень нравится упрощенный подход к использованию Funcs. Вот пример. Сначала добавьте это в свою ViewModel:

public abstract class ViewModelBase : INotifyPropertyChanged
{
    /** Other ViewModel Code *//

    public Func<string, string, bool> OkCancelDialog { get; set; }
}

Затем, когда вы создаете производный класс вашего ViewModel, вы просто присоединяете следующий код: (Обычно я делаю это при запуске, например Program.cs)

var myVM = new SomeSuperViewModel();
myVM.OkCancelDialog = (msg, caption) => MessageBox.Show(msg, caption, MessageBoxButton.OkCancel) == MessageBoxResult.OK;

В вашем фактическом коде ViewModel все, что вам нужно сделать, это вызвать:

if (OkCancelDialog("Some crazy message.", "Caption"))
    //do something if true
else
    //else do something if false

В ваших модульных тестах вы можете сделать это:

var myVMToTest = new SomeSuperViewModel();
myVMToTest.OkCancelDialog = (msg, caption) => true; //could be false too if you need to test that functionality.

Я предпочитаю этот подход, так как он прост и прост в тестировании. Что думают другие?

Ответ 3

Возможно, вы посмотрите пример приложения ViewModel (EmailClient) WPF Application Framework (WAF). Он показывает, как писать пользовательские диалоги с MVVM, и показывает, как вы можете использовать MessageBox без нарушения шаблона MVVM.

Ответ 4

Что не так с вызовом System.Windows.MessageBox.Show() из кода вашего ViewModel

например.

public bool GetConfirmation(string Message, string Caption)
{ return MessageBox.Show(Message, 
                         Caption, 
                         System.Windows.MessageBoxButton.OKCancel, 
                         System.Windows.MessageBoxImage.Question, 
                         System.Windows.MessageBoxResult.Cancel) == System.Windows.MessageBoxResult.OK; }