2

これは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];
    }
}

もしそうなら、私が表示しているダイアログのオプションを変更すると言うことをどのように許可する必要がありますか。dialog.something = something_elseたとえば、メソッドに多くの引数を追加せずに、別のダイアログに異なるダイアログオプションを持たせたい

4

2 に答える 2

5

ダイアログ自体の表示は、ViewModelでは発生しないはずです。私は通常、適切なDialogメソッド呼び出しとともにダイアログサービスインターフェイスIDialogServicesを提供します。次に、Viewクラスの1つ(通常はMainWindow)にこのインターフェイスを実装させ、実際のShowロジックを実行させます。これにより、ViewModelロジックが特定のビューから分離され、たとえば、ダイアログを開きたいコードを単体テストできるようになります。

次に、主なタスクは、サービスインターフェイスをそれを必要とするViewModelに挿入することです。これは、依存性注入フレームワークがある場合に最も簡単ですが、サービスロケーター(インターフェイスの実装を登録できる静的クラス)を使用してこれを行うことも、コンストラクターを介してインターフェイスをViewModelに渡すこともできます(ViewModelの方法によって異なります)。構築されます。)

于 2010-10-13T00:19:11.793 に答える
5

DialogServiceの使用は非常に重要なアプローチだと思います。Actions/Lambdasを使用してこの問題を処理するのが好きです。

ビューモデルには、これが宣言として含まれている場合があります。

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

次に、呼び出し元は次のようにビューモデルを作成します。

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

次に、次のように呼び出すことができます。

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

このタイプのアプローチは、テストに実際に役立ちます。テストでは、ビューモデルのリターンを好きなように定義できるためです。

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

    return result;
};

個人的には、このアプローチが最も単純だと思います。私は他の人の考えが大好きです。

于 2010-10-13T20:56:52.767 に答える