Хорошие подходы для моделей просмотра, чтобы породить диалог с собственной моделью представления и получения результатовC#

Место общения программистов C#
Ответить
Anonymous
 Хорошие подходы для моделей просмотра, чтобы породить диалог с собственной моделью представления и получения результатов

Сообщение Anonymous »

I've read a good number of approaches to getting a dialog spawned by a view model, and possibly providing some input to that dialog and then retrieving some output - I'm talking about a case where you have, for example, ViewA whose DataContext is ViewModelA, and at some point ViewModelA needs to spawn DialogB which has its own view model ViewModelb и, возможно, предоставьте вход в этот диалог и получите результат. Подход должен быть (1) достаточно простым, (2) способен обеспечить ввод в диалог, (3) способен породить диалог из Viewa , чтобы он мог быть должным образом владеть, (4) способен вернуть результат для ViewModela и (5), способный указать, был ли результат «принятие» или «канзал». И предпочтительно не требует дополнительных внешних зависимостей. < /P>
Я не был удовлетворен тем, что я нашел до сих пор. Некоторые из решений, которые я отклонил, слишком сложные - для потребности, которые очень распространены и были бы чрезвычайно просты в разрешении, если не использовать шаблон MVVM, не кажется, что это должно быть так сложно. Очевидно, что шаблон MVVM дает некоторые большие преимущества, которые по -прежнему делают его достойным шаблоном, но создание диалога для сбора некоторой информации в специальном окне, а затем вернуть результат к модели призывного представления является очень распространенной необходимостью - слишком распространенной для такой отсутствия ясности относительно того, как его достичь. Viewa никогда не знал о роскошном диалоге. И другие подходы не могут соответствовать, по крайней мере, одним из вышеуказанных критериев. Это не так удивительно просто, как было бы, если бы все было сделано в коде-заводе, но я нашел это достаточно простым, и никаких дополнительных внешних зависимостей. /> dialogeventargs.cs

Код: Выделить всё

public delegate void DialogEventHandler(DialogEventArgs args);

public class DialogEventArgs(TIn input) : EventArgs
{
public Window Dialog { get; set; }
public TIn Input { get; } = input;
public TOut Output { get; set; }
public bool Accepted { get; private set; }

public void ShowDialog(Window parentWindow)
{
Dialog.OwnerWindow = parentWindow;
Accepted = (bool)Dialog.ShowDialog();
}
}
Тогда мой базовый класс модели моего представления имеет событие запроса Colose для диалогов, которые можно использовать для сообщения родительского представления, чтобы закрыть:
viewmodelbase.cs
>

Код: Выделить всё

public abstract class ViewModelBase
{
public event EventHandler RequestClose;
protected void OnRequestClose()
{
RequestClose?.Invoke(this, EventArgs.Empty);
}
}
Модель представления для диалогового окна:
categoriesviewmodel.cs

Код: Выделить всё

public class CategoriesViewModel : ViewModelBase
{
private DialogEventArgs _dialogArgs;

public List SelectedCategories { get; } = [];

public CategoriesViewModel(DialogEventArgs args)
{
_dialogArgs = args;
var input = args.Input;
// do something with input - e.g. initialize a list or something
}

[RelayCommand]
public void Cancel()
{
// do some clean up work
OnRequestClose();
}

[RelayCommand]
public void Commit()
{
args.Output = SelectCategories;
OnRequestClose();
}
}
< /code>
Диалоговое окно передает Dialogeventargs в модель представления и подписывает, чтобы ответить на событие RequestClose. Он также предоставляет заводский метод для легкого построения диалога DialogeVentargs (так как этот диалог может использоваться на протяжении всего приложения).  
[b] categoriesdialog.cs[/b]образнойpublic partial class CategoriesDialog() : Window
{
public CategoriesDialog(DialogEventArgs args)
{
InitializeComponent();
var vm = new CategoriesViewModel(args);
DataContext = vm;
vm.RequestClose += (s, e) => Close();
}

public static DialogEventArgs GetDialogArgs(List input)
{
var args = new DialogEventArgs(input);
args.Dialog = new ChooseCategories(args);
return args;
}
}
Основное окно подписывается на событие запроса диалога основной модели представления:
mainwindow.cs

Код: Выделить всё

public class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
vm = new MainViewModel();
vm.RequestCategoriesDialog += args => args.ShowDialog(this);
}
}
и модель основного представления повышает событие и очень просто отвечает SO:
shrong> mainviewmodel.cs
public class MainViewModel : ViewModelBase
{
public event DialogEventHandler RequestCategoriesDialog;

public List CurrentCategories { get; } = [];

[RelayCommand]
private void UpdateCategories()
{
var args = CategoriesDialog.GetDialogArgs(CurrentCategories);
RequestCategoriesDialog?.Invoke(args);
if (args.Accepted)
{
// respond to acceptance
}
}
}
< /code>
Таким образом, обе модели представления остаются агностическими в отношении проблем пользовательского интерфейса, и оба пользовательских интерфейса являются агностическими в отношении входов и выходов, передаваемых обратно и полем с помощью моделей View и могут просто действовать как посланники между ними, при этом обеспечивая любое необходимое поведение пользовательского интерфейса. Если бы я больше реализовал это поведение, у меня, вероятно, был бы класс «DialogViewModelBase», чтобы сделать этот шаблон более повторяемым, но хотел бы сохранить вышеупомянутый пример от грибов.>

Подробнее здесь: https://stackoverflow.com/questions/797 ... del-and-re
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»