Обработка диалогов в WPF с помощью MVVM - PullRequest
226 голосов
/ 18 января 2009

В шаблоне MVVM для WPF обработка диалогов является одной из более сложных операций. Так как ваша модель представления ничего не знает о представлении, диалоговое общение может быть интересным. Я могу выставить ICommand, чтобы, когда представление вызывает его, мог появиться диалог.

Кто-нибудь знает хороший способ обработки результатов из диалогов? Я говорю о диалоговых окнах, таких как MessageBox.

Одним из способов, которым мы это сделали, было событие в модели представления, на которое представление подписывалось, когда требовался диалог.

public event EventHandler<MyDeleteArgs> RequiresDeleteDialog;

Это нормально, но это означает, что для представления требуется код, от которого я бы хотел остаться в стороне.

Ответы [ 23 ]

0 голосов
/ 28 марта 2009

Я боролся с той же проблемой. Я придумал способ связи между View и ViewModel. Вы можете инициировать отправку сообщения из ViewModel в View, чтобы показать ему окно сообщения, и оно сообщит результат. Затем ViewModel может ответить на результат, возвращенный из View.

Я демонстрирую это в моем блоге :

0 голосов
/ 27 января 2012

РЕДАКТИРОВАТЬ: да, я согласен, что это неправильный подход MVVM, и сейчас я использую что-то похожее на то, что предлагает вслепую.

Один из способов, которым вы могли бы это сделать, -

В вашей модели основного вида (где вы открываете модальный):

void OpenModal()
{
    ModalWindowViewModel mwvm = new ModalWindowViewModel();
    Window mw = new Window();
    mw.content = mwvm;
    mw.ShowDialog()
    if(mw.DialogResult == true)
    { 
        // Your Code, you can access property in mwvm if you need.
    }
}

А в вашем модальном окне View / ViewModel:

XAML:

<Button Name="okButton" Command="{Binding OkCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">OK</Button>
<Button Margin="2" VerticalAlignment="Center" Name="cancelButton" IsCancel="True">Cancel</Button>

ViewModel:

public ICommand OkCommand
{
    get
    {
        if (_okCommand == null)
        {
            _okCommand = new ActionCommand<Window>(DoOk, CanDoOk);
        }
        return _okCommand ;
    }
}

void DoOk(Window win)
{
    <!--Your Code-->
    win.DialogResult = true;
    win.Close();
}

bool CanDoOk(Window win) { return true; }

или аналогично тому, что размещено здесь WPF MVVM: как закрыть окно

0 голосов
/ 18 января 2009

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

Мое текущее решение выглядит так:

public class SelectionTaskModel<TChoosable> : ViewModel
    where TChoosable : ViewModel
{
    public SelectionTaskModel(ICollection<TChoosable> choices);
    public ReadOnlyCollection<TChoosable> Choices { get; }
    public void Choose(TChoosable choosen);
    public void Abort();
}

Когда модель представления решает, что требуется ввод пользователя, она вызывает экземпляр SelectionTaskModel с возможными вариантами выбора для пользователя. Инфраструктура заботится о создании соответствующего представления, которое своевременно вызовет функцию Choose() по выбору пользователя.

...