Я не был удовлетворен тем, что я нашел до сих пор. Некоторые из решений, которые я отклонил, слишком сложные - для потребности, которые очень распространены и были бы чрезвычайно просты в разрешении, если не использовать шаблон 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();
}
}
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);
}
}
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
Мобильная версия