Question

Je me demande est-ce la façon de montrer les boîtes de dialogue dans MVVM?

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];
    }
}

Si oui, comment dois-je me permettre de dire modifier les options de dialogues que je montre. Exemple, je veux une autre boîte de dialogue d'avoir les différentes options de dialogue dialog.something = something_else sans ajouter beaucoup d'arguments à ma méthode

Était-ce utile?

La solution

Affichage de la boîte de dialogue lui-même ne devrait pas se produire dans un ViewModel. Je donne généralement un IDialogServices d'interface de service de dialogue, avec des appels de méthode de dialogue appropriés. J'ai alors l'une des classes de vue (généralement la mise en œuvre de mainWindow) cette interface et exécuter la logique Afficher réelle. Cela isole votre logique ViewModel spécifique de la vue et, par exemple, vous permet de code de test unitaire qui veut ouvrir une boîte de dialogue.

La tâche principale est ensuite injecter l'interface de service dans le ViewModel qui en a besoin. Ceci est plus facile si vous avez un cadre d'injection de dépendance, mais vous pouvez aussi le faire avec un service de localisation (une classe statique où vous pouvez enregistrer les implémentations d'interface) ou passer l'interface avec le ViewModel par son constructeur (dépend de la façon dont votre ViewModels sont construits.)

Autres conseils

Je pense que l'aide d'un DialogService est une approche poids lourd. Je aime utiliser Actions / lambdas pour gérer ce problème.

Votre modèle de vue pourrait avoir cela comme une déclaration:

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

L'appelant alors créer votre modèle de vue comme ceci:

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;
};

Vous pouvez ensuite l'appeler comme:

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

Ce type d'approche est vraiment utile pour les tests. Parce que vos tests peuvent définir le retour sur votre modèle en vue d'être ce qu'ils veulent:

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

    return result;
};

Personnellement, je trouve que cette approche est la plus simpliste. J'aimerais d'autres pensées de pour.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top