ОК, отмените Dialog MVVM Pattern wpf. Как я могу это сделать? - PullRequest
12 голосов
/ 17 ноября 2010

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

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

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

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

Ответы [ 4 ]

13 голосов
/ 17 ноября 2010

это диалоговое окно с кнопками ОК и Отмена.Я включил 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.

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

8 голосов
/ 17 ноября 2010

Я думаю, что все остальные, которые используют 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.

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

0 голосов
/ 13 октября 2011

Что не так с простым вызовом 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; }
0 голосов
/ 17 ноября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...