Pregunta

Me pregunto ¿es esta la manera de mostrar los cuadros de diálogo en 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 es así, ¿cómo debo permitir que me dicen modificar las opciones en los cuadros de diálogo que estoy mostrando. Ejemplo, quiero otro cuadro de diálogo que tienen diferentes opciones de diálogo dialog.something = something_else sin añadir un montón de argumentos para mi método

¿Fue útil?

Solución

Mostrando el diálogo en sí no debería ocurrir en un modelo de vista. Por lo general proporcionan un diálogo IDialogServices interfaz de servicio, con llamadas apropiadas método de diálogo. entonces tengo una de las clases de vista (por lo general el MainWindow) implementar esta interfaz y llevar a cabo la Exposición lógica real. Esto aísla la lógica del modelo de vista específico y Ver, por ejemplo, le permite al código de prueba de unidad que quiere abrir un diálogo.

La principal tarea es entonces la inyección de la interfaz de servicio en el modelo de vista que lo necesita. Esto es más fácil si usted tiene un marco de dependencia de la inyección, pero también se puede hacer esto con un servicio de localización (una clase estática donde se puede registrar implementaciones de interfaz) o pasar la interfaz con el modelo de vista a través de su constructor (depende de cómo sus ViewModels están construidos.)

Otros consejos

Creo que el uso de un DialogService es un enfoque de alto gramaje. Me gusta usar acciones / Lambdas de manejar este problema.

Su modelo de vista podría tener esto como una declaración:

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

A continuación el comunicante crearía su modelo de vista de esta manera:

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

A continuación, puede llamar así:

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

Este tipo de enfoque realmente vale la pena para la prueba. Debido a que las pruebas pueden definir el retorno de su modelo de vista para ser lo que quieran:

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

    return result;
};

En lo personal, me parece que este enfoque es el más simplista. Me encantaría otros de pensamientos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top