Gute Ansätze für Ansichtsmodelle, um einen Dialog mit seinem eigenen Ansichtsmodell und den Ergebnissen zu erzeugenC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Gute Ansätze für Ansichtsmodelle, um einen Dialog mit seinem eigenen Ansichtsmodell und den Ergebnissen zu erzeugen

Post by Anonymous »

Ich habe eine gute Anzahl von Ansätzen zum Erhalten eines Dialogfelds durch ein Ansichtsmodell gelesen und möglicherweise einen Eingang in diesen Dialogfeld und dann eine Ausgabe abrufen. Ich spreche von einem Fall, in dem Sie beispielsweise Viewa haben, dessen DataContext ViewModela und irgendwann Sichtmodell. ViewModelB und möglicherweise eine Eingabe für diesen Dialog angeben und ein Ergebnis abrufen. Der Ansatz muss (1) einigermaßen einfach sein, (2) in der Lage sein, Eingaben in den Dialog zu liefern, (3) in der Lage, den Dialog aus Viewa zu leiten, damit er ordnungsgemäß besessen werden kann, (4) in der Lage sind, ein Ergebnis an ViewModela und (5) anzuzeigen, in der Lage sind, wenn das Ergebnis ein "Akzeptanz" oder eine "Stornierung" oder eine "Stornierung" "oder eine" Stornierung "" oder eine "Stornierung" "oder eine" Stornierung ". Und erfordern vorzugsweise keine zusätzlichen externen Abhängigkeiten. < /P>
Ich war jedoch nicht zufrieden mit dem, was ich bisher gefunden habe. Einige der Lösungen, die ich so weit zu komplex abgetan habe - für ein Bedarf, das sehr häufig ist und extrem einfach zu lösen wäre, wenn es das MVVM -Muster nicht verwendet, scheint es nicht so schwierig zu sein. Offensichtlich bietet das MVVM -Muster einige große Vorteile, die es immer noch zu einem würdigen Muster machen, aber ein Dialog zum Sammeln einiger Informationen in einem speziellen Fenster und dann ein Ergebnis des Aufrufansichtsmodells ist ein sehr häufiges Bedürfnis - zu häufig, um es zu einem solchen Mangel an Klarheit zu geben, wie man es mit dem Erreichen des Sichts -Modells einsteht. Viewa hat nie Kenntnis des Dialogfelds für den hervorgebrachten Dialog. Und andere Ansätze erfüllen nicht mindestens eines der oben genannten Kriterien. Es ist nicht so wunderbar einfach wie es wäre, wenn alles in Code-Behind erfolgen würde, aber ich fand es recht einfach, und es sind keine zusätzlichen externen Abhängigkeiten erforderlich. />
DIALOGEVENTARGS.CS

Code: Select all

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();
}
}
Dann hat meine Ansichtsmodell -Basisklasse ein RequestClose -Ereignis für Dialoge, mit denen die übergeordnete Ansicht zu schließen ist:
ViewModelBase.cs

Code: Select all

public abstract class ViewModelBase
{
public event EventHandler RequestClose;
protected void OnRequestClose()
{
RequestClose?.Invoke(this, EventArgs.Empty);
}
}
Das Ansichtsmodell für den Dialogfeld:
categoriesViewModel.cs

Code: Select all

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>
Das Dialogfenster übergibt das DialogEnventArgs an das Ansichtsmodell und zeichnet sich ab, um auf das RequestClose -Ereignis zu antworten.  Es bietet auch eine Werksmethode zum Erstellen der DialogEGEventArgs (da dieses Dialogfeld in der gesamten Anwendung verwendet werden kann).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;
}
}
Das Hauptfenster zeichnet sich für das Dialoganforderungsereignis des Hauptansichtsmodells an:
mainwindow.cs

Code: Select all

public class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
vm = new MainViewModel();
vm.RequestCategoriesDialog += args => args.ShowDialog(this);
}
}
und das Hauptansichtsmodell erhöht das Ereignis und reagiert sehr einfach wie SO:
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>
Auf diese Weise bleiben beide Ansichtsmodelle in Bezug auf UI-Bedenken agnostisch, und beide UIs sind agnostisch über die Eingaben und Ausgänge, die von den View-Modellen hin und her übergeben werden und können einfach als Boten zwischen den beiden fungieren, während das erforderliche UI-Verhalten durchgesetzt wird. Wenn ich dieses Verhalten mehr implementieren würde, hätte ich wahrscheinlich eine "DialogViewModelBase" -Klasse, um dieses Muster wiederholbarer zu machen, wollte das obige Beispiel jedoch zu viel Pilzing abhalten.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post