Frage

Ich frage mich, ist dies der Weg Dialoge in MVVM zu zeigen?

public ICommand OpenFileCommand
{
    get
    {
        if (_openFileCommand == null) {
            _openFileCommand = new RelayCommand(delegate
            {
                var strArr = DialogsViewModel.GetOpenFileDialog("Open a file ...", "Text files|*.txt | All Files|*.*");
                foreach (string s in strArr) {
                    // do something with file
                }
            });
        }
        return _openFileCommand;
    }
}

public class DialogsViewModel {
    public static string[] GetOpenFileDialog(string title, string filter)
    {
        var dialog = new OpenFileDialog();
        dialog.Title = title;
        dialog.Filter = filter;
        dialog.CheckFileExists = true;
        dialog.CheckPathExists = true;
        dialog.Multiselect = true;
        if ((bool)dialog.ShowDialog()) {
            return dialog.SafeFileNames;
        }
        return new string[0];
    }
}

Wenn ja, wie soll ich mich erlauben die Optionen auf Dialoge zu sagen ändern Ich bin zeigen. Beispiel möchte ich ein weiteres Dialog verschiedene Dialogoptionen dialog.something = something_else ohne meine Methode eine Menge Argumente zu hinzugefügt haben,

War es hilfreich?

Lösung

Zeigen Sie den Dialog selbst nicht in einem Ansichtsmodell passieren soll. Ich in der Regel eine Dialog-Service-Schnittstelle IDialogServices mit entsprechenden Dialog Methodenaufrufen. Ich habe dann eine der Ansicht Klassen (in der Regel der Mainwindow) diese Schnittstelle implementieren und die eigentliche Show-Logik durchzuführen. Dies isoliert Ihre Ansichtsmodell Logik aus der spezifischen Ansicht und zum Beispiel, über die Sie Unit-Test-Code will einen Dialog öffnen.

Die Hauptaufgabe wird dann die Service-Schnittstelle in das Ansichtsmodell Injektion, die es braucht. Dies ist am einfachsten, wenn Sie eine Abhängigkeit-Injection-Framework, aber Sie können dies auch mit einem Service-Locator (eine statische Klasse, wo Sie Interface-Implementierungen registrieren können) oder die Schnittstelle zum Ansichtsmodell durch den Konstruktor übergeben (hängt davon ab, wie Sie Ihre Viewmodels konstruiert.)

Andere Tipps

Ich denke, ein DialogService verwendet, ist ein schwergewichtiger Ansatz. Ich mag mit Aktionen / Lambdas dieses Problem zu behandeln.

Ihre Ansicht Modell könnte dies hat als eine Erklärung:

public Func<string, string, dynamic> OpenFileDialog { get; set; }

Der Anrufer dann würde Ihre Ansicht Modell erstellen wie folgt:

var myViewModel = new MyViewModel();
myViewModel.OpenFileDialog = (title, filter) =>
{
    var dialog = new OpenFileDialog();
    dialog.Filter = filter;
    dialog.Title = title;

    dynamic result = new ExpandoObject();
    if (dialog.ShowDialog() == DialogResult.Ok) {
        result.Success = true;
        result.Files = dialog.SafeFileNames;
    }
    else {
        result.Success = false;
        result.Files = new string[0];
    }

    return result;
};

Sie könnten dann nennen Sie es wie:

dynamic res = myViewModel.OpenFileDialog("Select a file", "All files (*.*)|*.*");
var wasSuccess = res.Success;

Dieser Ansatz zahlt sich aus für die Prüfung. Da die Tests können die Rendite Ihrer Ansicht Modell definieren, was sie zu sein wie:

 myViewModelToTest.OpenFileDialog = (title, filter) =>
{
    dynamic result = new ExpandoObject();
    result.Success = true;
    result.Files = new string[1];
    result.Files[0] = "myexpectedfile.txt";

    return result;
};

Ich persönlich diesen Ansatz finden die meisten simpel sein. Ich würde andere Gedanken lieben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top