Окно MVVM / Операции управления - PullRequest
2 голосов
/ 26 августа 2010

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

I 'Я столкнулся с небольшой дилеммой, мне нужно скрыть / закрыть окно, основанное на некоторой логике в одном из методов в модели представления.

Я не могу на всю жизнь придумать надежный способсделать это.Я связал свойство Visibility с параметром Visibility DP окна, который работает (что-то вроде), но как бы я назвал Close() в диалоговом окне?

Я использую MVVM View-First, поэтому модель представленияне знает представления, представление создает экземпляр модели представления (через DI / IoC) и устанавливает ее как DataContext.

Команды работают неправильно, события исключаются, если я не связываюсь с нимв коде, за которым стоит кое-что, а не делать, если есть MVVM способ сделать это, который не совсем запутан.

Есть идеи от большого SO-сообщества?

Или, может быть, ячего-то не хватает в MVVM вообще?В любом случае, дайте мне знать: o

Ответы [ 3 ]

5 голосов
/ 27 августа 2010

Как это часто бывает, есть много способов снять кожу с этой кошки.

Один из способов сделать это без указания кода в представлении - использовать прикрепленное поведение, например следующее:

public static class CloseBehavior 
{
    public static bool GetCloseWhen(DependencyObject obj)
    {
        return (bool)obj.GetValue(CloseWhenProperty);
    }

    public static void SetCloseWhen(DependencyObject obj, bool value)
    {
        obj.SetValue(CloseWhenProperty, value);
    }

    public static readonly DependencyProperty CloseWhenProperty =
        DependencyProperty.RegisterAttached(
            "CloseWhen", typeof(bool), typeof(CloseBehavior), 
            new UIPropertyMetadata(OnCloseWhenChanged));
    // the lone parameter in the UIPropertyMetadata is a callback
    // for when the property value changes

    static void OnCloseWhenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // if false, we're not concerned with it
        if(!(bool)e.NewValue) return;

       // if attached to something other than a window, this doesn't make sense
        var win = d as Window;

        if(d == null) return;

            // close the window
        win.Close();
    }
}

В вашем XAML:

<Window x:Class="WpfApplication1.Window1"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication1" 

     local:CloseBehavior.CloseWhen="{Binding ViewModelWorkComplete}"
>
<! -- content -->
</Window>

Где ViewModelWorkComplete - это просто логическое свойство в модели представления.

Эффект заключается в том, что когда модель представления устанавливает ViewModelWorkComplete в true (и вызывает соответствующее событие INotifyPropertyChanged), окно будет закрыто.

2 голосов
/ 27 августа 2010

Что плохого в событиях и подписке в коде?Закрытие окна - это вещь, специфичная для презентации, и оно, безусловно, принадлежит View.

Основными целями здесь являются тестируемость и разделение проблем, и вы можете легко проверить, что ViewModel инициирует конкретное событие.

1 голос
/ 27 августа 2010

Используя шаблон Mediator или другие механизмы обработки событий, вы можете вызывать определенные события модели представления (например, «SaveDone» или «NoDataRemaining» и т. Д.). Затем сделайте свой взгляд, чтобы слушать эти события; основываясь на них, окно может решить закрыть себя.

Если для пользователя есть более явный способ сказать «Закрыть» (например, нажав кнопку «Закрыть» в окне), мы надеемся, что это можно сделать исключительно в окне.

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