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

Показать диалог с MVVM Light toolkit

У меня есть ViewModel, который должен показывать модальное окно (используя ShowDialog()) при нажатии кнопки. ViewModel ловит команду щелчка, но я не хочу делать window.ShowDialog() в моей модели ViewModel. Я знаю, что в MVVM Light есть DialogMessage, но используется для отображения ящиков сообщений, а не модальных окон WPF.

Любые идеи о том, как это сделать?

4b9b3361

Ответ 1

Вы должны использовать класс Messenger. На View зарегистрируйте сообщение для отображения окна, а затем, когда вам нужно показать его, вызовите метод Send класса Messenger.

Вы можете сделать что-то вроде этого:

//do this in code behind file of your View
Messenger.Default.Register<string>(this, ShowWindow);

private void ShowWindow(string message)
{
    // your logic here
}

// In the ViewModel
Messenger.Default.Send("Some text");

Ответ 2

Это то, что я использую для пользовательских диалогов с MVVM-Light Toolkit.

Сначала определите эти четыре класса где-нибудь в вашем приложении. Класс MessageBase является частью набора инструментов.

public class ShowChildWindowMessage : MessageBase { }
public class HideChildWindowMessage : MessageBase { }
public class DisplaySomeContentMessage : MessageBase { }
public class DisplaySomeOtherContentMessage : MessageBase { }

Во-вторых, вам нужно "детское" окно управления. Создайте файл XAML со следующим содержимым:

<Window x:Class="ChildWindowView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="{Binding Path=ChildWindowBinding, Source={StaticResource Locator}}"
    Title="{Binding Path=CurrentContent.DisplayName}"
    MinWidth="300" MinHeight="125" SizeToContent="WidthAndHeight"
    ShowInTaskbar="False" WindowState="Normal" ResizeMode="NoResize"
    WindowStartupLocation="CenterOwner" SnapsToDevicePixels="True">

<Grid>
    <ContentPresenter Content="{Binding Path=CurrentContent}" />
</Grid>

Затем добавьте следующее в код этого файла XAML:

public partial class ChildWindowView : Window
{
    public ChildWindowView(Window owner)
    {
        InitializeComponent();
        Owner = owner;

        Closing += (s, e) => 
        {
            // window reused so just hide
            e.Cancel = true;
            Messenger.Default.Send(new HideChildWindowMessage());
        };
    }

}

В-третьих, добавьте следующее в код вашего файла MainWindow.xaml:

public partial class MainWindowView : Window
{
    private ChildWindowView m_childWindowView;

    public MainWindowView()
    {
        InitializeComponent();
        Closing += (s, e) => ViewModelLocator.CleanUp();
        Loaded += (s, e) =>
        {
            m_childWindowView = new ChildWindowView(this);
        };

        Messenger.Default.Register<ShowChildWindowMessage>(this, (msg) => m_childWindowView.ShowDialog());
        Messenger.Default.Register<HideChildWindowMessage>(this, (msg) => m_childWindowView.Hide());
    }
}

В-четвертых, определите следующую модель представления:

public class ChildWindowVM : ViewModelBase
{
    private ViewModelBase m_currentContent;
    public ViewModelBase CurrentContent
    {
        get { return m_currentContent; }
        set
        {
            m_currentContent = value;
            RaisePropertyChanged("CurrentContent");

            if (m_currentContent != null)
            {
                Messenger.Default.Send(new ShowChildWindowMessage());
            }
        }
    }

    public ChildWindowVM()
    {
        Messenger.Default.Register<DisplaySomeContentMessage>(this, (msg) => CurrentContent = ViewModelLocator.SomeContentVm);
        Messenger.Default.Register<DisplaySomeOtherContentMessage>(this, (msg) => CurrentContent = ViewModelLocator.SomeOtherContentVm);
    }
}

В-пятых, вы создаете файлы XAML и просматриваете модели для содержимого, которое вы хотите отобразить в своем настраиваемом диалоговом окне. В этом примере мои модели просмотра содержимого были названы SomeContent и SomeOtherContent. Разумеется, вы замените их тем, что захотите.

Наконец, для того, чтобы это сработало, вы должны привязать модели представления контента к их соответствующим файлам XAML, добавив следующие ресурсы приложения:

<DataTemplate DataType="{x:Type viewmodels:SomeContentVM}">
    <views:SomeContentView/>
</DataTemplate>

<DataTemplate DataType="{x:Type viewmodels:SomeOtherContentVM}">
    <views:SomeOtherContentView/>
</DataTemplate>

Теперь, как только вы получите все это, очень легко добавить новый контент (модели XAML и просмотра), которые могут отображаться в вашем дочернем окне. Чтобы отобразить контент, просто вызовите соответствующее сообщение с помощью класса Messenger:

Messenger.Default.Send(new DisplaySomeContentMessage ());

Сообщите мне, если мне нужно прояснить любую часть этого для вас.

Ответ 3

Для всех вас, кто хочет действительно простого решения, и все в порядке с не-100% -clean-MVVM:
Я хотел открыть диалог подключения из моего главного окна и сделал следующее

Сначала я дал моему MainWindow имя:

<Window x:Name="MainWindow">

Затем я создал команду в моей MainWindowViewModel:

public ICommand AddInterfaceCommand
{
    get
    {
        return new RelayCommand<Window>((parentWindow) =>
        {
            var wizard = new ConnectionWizard();
            wizard.Owner = parentWindow;
            wizard.ShowDialog();
        }
    }
}

Я привязал свою кнопку в MainWindow к команде и передал само окно (родительское окно для диалога):

<Button Command="{Binding AddInterfaceCommand}" CommandParameter="{Binding ElementName=MainWindow}">Add interface</Button>

Что все.

Только оговорка: получение возвращаемых значений из Viewmodel диалогового окна может быть затруднено. Мне не нужна эта функция.

Ответ 4

Вы можете определить интерфейс и его реализацию следующим образом. И, конечно же, с контейнером для инъекций зависимостей, вы должны сделать что-то вроде этого.

NInjectKernel.Bind<IMessageBoxService>().To<MessageBoxService>();

Ваша ViewModel будет выглядеть примерно так.

    private IMessageBoxService _MBService;
    public DropboxSettingsViewModel(IDropboxService dbService, IMessageBoxService mbService)
    {
        if (dbService == null)
            throw new ArgumentNullException("IDropboxService is null");

        _DropboxService = dbService;

        if (mbService == null)
            throw new ArgumentNullException("MessageBoxService is null");

        _MBService = mbService;

    }

Ваш метод выполнения команды click будет выглядеть следующим образом.

    private void ConfigureDropboxExecute(object obj)
    {

        _MBService.Show("Error Occured Authenticating dropbox", "Dropbox Authentication", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);

    }


public interface  IMessageBoxService
{
    MessageBoxResult Show(string messageBoxText);
    MessageBoxResult Show(string messageBoxText, string caption);
    MessageBoxResult Show(Window owner, string messageBoxText);
    MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button);
    MessageBoxResult Show(Window owner, string messageBoxText, string caption);
    MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon);
    MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button);
    MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult);
    MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon);
    MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options);
    MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult);
    MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options);
}

с использованием System.Windows;

public class MessageBoxService : IMessageBoxService
{
    public MessageBoxResult Show(string messageBoxText)
    {
        return MessageBox.Show(messageBoxText);
    }

    public MessageBoxResult Show(Window owner, string messageBoxText)
    {
        return MessageBox.Show(owner, messageBoxText);
    }

    public MessageBoxResult Show(string messageBoxText, string caption)
    {
        return MessageBox.Show(messageBoxText, caption);
    }

    public MessageBoxResult Show(Window owner, string messageBoxText, string caption)
    {
        return MessageBox.Show(owner, messageBoxText, caption);
    }

    public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button)
    {
        return MessageBox.Show(messageBoxText, caption, button);
    }

    public MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button)
    {
        return MessageBox.Show(owner, messageBoxText, caption, button);
    }

    public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
    {
        return MessageBox.Show(messageBoxText, caption, button, icon);
    }

    public MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
    {
        return MessageBox.Show(owner, messageBoxText, caption, button, icon);
    }

    public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
    {
        return MessageBox.Show(messageBoxText, caption, button, icon, defaultResult);
    }

    public MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
    {
        return MessageBox.Show(owner, messageBoxText, caption, button, icon, defaultResult);
    }

    public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
    {
        return MessageBox.Show(messageBoxText, caption, button, icon, defaultResult, options);
    }

    public MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
    {
        return MessageBox.Show(owner, messageBoxText, caption, button, icon, defaultResult, options);
    }
}