عرض مربعات حوار في خيارات مربع الحوار MVVM & Setting

StackOverflow https://stackoverflow.com/questions/3919974

  •  29-09-2019
  •  | 
  •  

سؤال

أنا فقط أتساءل هل هذه هي الطريقة لعرض الحوار في 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 دون إضافة الكثير من الحجج إلى طريقتي

هل كانت مفيدة؟

المحلول

لا ينبغي أن يحدث إظهار الحوار نفسه في ViewModel. عادةً ما أقوم بتقديم واجهة خدمة مربع الحوار IdialogServices ، مع مكالمات طريقة الحوار المناسبة. بعد ذلك ، لدي واحدة من فئات العرض (عادةً ما يكون mainwindow) تنفيذ هذه الواجهة وأداء منطق العرض الفعلي. هذا يعزل منطق ViewModel الخاص بك من العرض المحدد ، وعلى سبيل المثال ، يتيح لك وحدة اختبار وحدة الاختبار التي تريد فتح مربع حوار.

تتمثل المهمة الرئيسية بعد ذلك في ضخ واجهة الخدمة في ViewModel التي تحتاجها. يكون هذا أسهل إذا كان لديك إطار عمل لحقن التبعية ، ولكن يمكنك أيضًا القيام بذلك باستخدام محامي الخدمة (فئة ثابتة حيث يمكنك تسجيل تطبيقات الواجهة) أو تمرير الواجهة إلى ViewModel من خلال مُنشئها (يعتمد على كيفية ViewModels شيدت.)

نصائح أخرى

أعتقد أن استخدام مربع الحوار هو نهج الوزن الثقيل. أحب استخدام الإجراءات/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;
};

أنا شخصياً أجد أن هذا النهج هو الأكثر بساطة. أحب أفكار الآخرين.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top