سؤال

لدي تطبيق WPF الذي يستدعي MessageBox.Show () طريقة العودة في ViewModel (للتحقق مما إذا كان المستخدم يريد حقا حذف). هذا يعمل في الواقع, ، لكن يذهب ضد حبة MVVM نظرا لأن ViewModel لا ينبغي أن يحدد صراحة ما يحدث في الرأي.

حتى الآن أنا أفكر كيف يمكنني تنفيذ أفضل وظيفة messageBox.show () في تطبيق MVVM الخاص بي، خيارات:

  1. يمكن أن يكون لدي رسالة مع النص "هل أنت متأكد من ..." جنبا إلى جنب مع اثنين من الأزرار نعم ولا كل ذلك في حدود في XAML الخاص بي، وإنشاء مشغل على القالب بحيث تنهار / مرئي بناء على Viewmodelproperty يسمى aryoursurediorgoGoGibisible., ، ثم عندما أحتاج إلى مربع الحوار هذا، قم بتعيين aryoursurediorgoGoGiGibisibleAgevisible "True"، وكذلك التعامل مع الأزرار عبر التفويض مرة أخرى في Viewmodel.

  2. يمكن أن أحاول أيضا بطريقة ما التعامل مع هذا مع المشغلات في XAML بحيث يظهر زر الحذف في الواقع بعض عنصر الحدود مع الرسالة والأزرار الموجودة فيه، والزر نعم قام في الواقع بالحذف في الواقع.

يبدو أن الحلول معقدة للغاية لما اعتاد أن يكون خطوطا من التعليمات البرمجية مع messageBox.Show ().

في أي طرق قمت بتنفيذ مربعات الحوار بنجاح في تطبيقات MVVM الخاصة بك؟

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

المحلول

من الاثنين الذي تذكره، أفضل الخيار رقم 2. زر حذف على الصفحة فقط يجعل ظهور "حوار" تأكيد حذف ". "حوار تأكيد حذف" ينطلق فعلا الحذف.

هل راجعت كارل شيفليت خط WPF من شرائح الأعمال والعروض التوضيحيةب أعلم أنه يفعل شيئا كهذا. سأحاول أن أتذكر أين.

تحرير: تحقق من التحقق من صحة البيانات في mvvm KARL يدعو نافذة منبثقة من ViewModal (ماذا !؟ :-). أنا فعلا أحب فكرتك أفضل. يبدو أسهل في اختبار الوحدة.

نصائح أخرى

خدمات الإنقاذ. استخدام onyx. (إخلاء المسئولية، أنا المؤلف) هذا سهل مثل:

public void Foo()
{
    IDisplayMessage dm = this.View.GetService<IDisplayMessage>();
    dm.Show("Hello, world!");
}

في تطبيق قيد التشغيل، سيتصل هذا بشكل غير مباشر MessageBox.Show ("Hello، World!"). عند الاختبار، يمكن سحب خدمة IDisPlayMessage وتزويدها إلى ViewModel للقيام بما تريد تحقيقه أثناء الاختبار.

للتوسع في إجابة عميد الطباشير الآن أن رابطه هو كابوت:

في ملف app.xaml.cs نحن ربط مربع حوار تأكيد إلى ViewModel.

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    var confirm = (Func<string, string, bool>)((msg, capt) => MessageBox.Show(msg, capt, MessageBoxButton.YesNo) == MessageBoxResult.Yes);
    var window = new MainWindowView();
    var viewModel = new MainWindowViewModel(confirm);
    window.DataContext = viewModel;
    ...
}

في طريقة العرض (mainwindowview.xaml) لدينا زر يستدعي أمر في ViewModel

<Button Command="{Binding Path=DeleteCommand}" />

يستخدم ViewModel (MainWindowViewModel.cs) أمر مفوض لإظهار "هل أنت متأكد؟" مربع الحوار وأداء الإجراء. في هذا المثال هو SimpleCommand مشابه ل هذه, ، ولكن أي تنفيذ ICommand يجب القيام به.

private readonly Func<string, string, bool> _confirm;

//constructor
public MainWindowViewModel(Func<string, string, bool> confirm)
{
    _confirm = confirm;
    ...
}

#region Delete Command
private SimpleCommand _deleteCommand;
public ICommand DeleteCommand
{
    get { return _deleteCommand ?? (_deleteCommand = new SimpleCommand(ExecuteDeleteCommand, CanExecuteDeleteCommand)); }
}

public bool CanExecuteDeleteCommand()
{
    //put your logic here whether to allow deletes
    return true;
}

public void ExecuteDeleteCommand()
{
    bool doDelete =_confirm("Are you sure?", "Confirm Delete");
    if (doDelete)
    {
        //delete from database
        ...
    }
}
#endregion

أنا فقط إنشاء واجهة (Imessagedisplay أو ما شابه ذلك) التي يتم حقنها في VM، ولديها طرق مثل MessageBox (ShowMessage () إلخ). يمكنك تطبيق ذلك باستخدام صندوق رسائل قياسي، أو أي شيء أكثر محددة WPF (أستخدمه هذا واحد على codeplex بعض الرجل دعا براجيش).

بهذه الطريقة فصل كل شيء ويمكن اختبارها.

ماذا عن رفع حدث مثل "MessageBoxRequested" يتم التعامل معها في CodeBehind من الرأي (على أي حال، فمنظر رمز فقط لذلك لا أرى أي مشكلة في وجود هذا الرمز على CodeBehind).

لقد قمت بإجراء عنصر تحكم غلاف رسوما بسيطا بالنسبة لنا لاستخدامه في حل MVVM النقي وما زال يسمح بإمكانيات اختبار الوحدة. التفاصيل في مدونتي http://geekswithblogs.net/mukapu/archive/201/201/2016/03/12/user-prompts-messageBox-with-mvvm.aspx.

ميكابو

لقد قمت بتنفيذ سلوك يستمع إلى رسالة من ViewModel. يعتمد على حل Laurent Bugnion، ولكن نظرا لأنه لا يستخدم التعليمات البرمجية وهو أمر قابل لإعادة الاستخدام أكثر، أعتقد أنه أكثر أناقة.

تحقق من ذلك هنا

WPF و Silverlight MessageBoxes

دعم MVVM

http://slwpfmessageBox.codeplex.com/

فقط في حالة أي شخص آخر لا يزال يقرأ وغير راض:

أردت فقط التعامل مع صناديق الرسائل "الإخطار" (أي لا أهتم DialogResult)، ولكن المشكلة التي لدي مع معظم الحلول التي قرأتها عنها هي أنها تبدو غير مباشرة في اختيار تنفيذ طريقة العرض الخاص بك (أي حاليا لدي MessageBox.Show, ، ولكن إذا قررت لاحقا كمزام فقط بوضوح لوحة مخفية مباشرة في رأيي، فلن يتمكن ذلك بشكل جيد للغاية مع INotification واجهة مرت إلى ViewModel).

لذلك ذهبت لسريع وقذرة:

ViewModel لديه string NotificationMessage الممتلكات، مع التغييرات PropertyChanged.

عرض المشترك ل PropertyChanged, ، وإذا كان يرى NotificationMessage الممتلكات تأتي من خلال، هل كل ما تريد.

حسنا، وهذا يعني أن الرأي لديه رمز وراء، واسم PropertyChanged مشفرة بشدة، لكن سيكون من الصعب الترميز في XAML على أي حال. وهذا يعني أنني أتجنب كل الأشياء مثل المحولات للحصول على الرؤية، والخصائص ليقول ما إذا كان الإخطار لا يزال مرئيا أم لا.

(من المسلم به أن هذا هو فقط لحالة استخدام محدودة (النار ونسيان)، لم أذكر الكثير من التفكير في الطريقة التي قد أرغب في تمديدها.)

أود فقط رميها من VM. لا أريد أن أضطر إلى استخدام خدمة شخص آخر أو اكتب بلدي فقط لرمي صندوق message.

لقد مررت مؤخرا في هذه المشكلة حيث اضطررت إلى استبدال MessageBox.Show في ViewModels مع بعض آلية مربع رسالة رسالة شكوى MVVM بالكامل.

لتحقيق هذا اعتدت InteractionRequest<Notification> و InteractionRequest<Confirmation> جنبا إلى جنب مع مشغلات التفاعل وكتب وجهات نظري الخاصة بصندوق الرسالة.

ما قمت بنشره هنا

هناك الكثير من الإجابات حول هذا الموضوع الذي يختلف من إنشاء فئة مخصصة لاستخدام مكتبات الطرف الثالث. أود أن أقول استخدام مكتبة طرف ثالث إذا كنت تريد أن تنبثق بارد مع وجود صور لطيفة.

ولكن إذا كنت ترغب فقط في استخدام مربع الرسالة العادية من Microsoft للحصول على تطبيق WPF الخاص بك هنا هو تطبيق MVVM / Unit ودية:

في البداية اعتقدت أنني سوف ترث فقط من مربع الرسالة ولفها مع واجهة ولكن لم أستطع بسبب مربع رسالة عدم وجود منشئ عام، لذلك هنا هو الحل "السهل":

مربع رسالة فك الترصم في Visual Studio، يمكنك رؤية جميع الأحوال الزائدة من الطريقة، فقد قمت بإنشاء تلك التي أردتها بعد ذلك، ثم قمت بإنشاء فئة جديدة وأضفت الأساليب، ملفوفة بواجهة و TA-DA! الآن يمكنك استخدام Ninject لربط الواجهة والطبقة، ثم حقنها واستخدام موك إلى اختبار الوحدة وغيرها

قم بإنشاء واجهة (أضفت فقط عدد قليل من الحمل الزائد لأنني لا أحتاج إليها جميعا):

public interface IMessageBox
    {
        /// <summary>Displays a message box that has a message, title bar caption, and button; and that returns a result.</summary>          
        MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button);

        /// <summary>Displays a message box that has a message, title bar caption, button, and icon; and that returns a result.</summary>           
        MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon);

        /// <summary>Displays a message box that has a message and title bar caption; and that returns a result.</summary>            
        MessageBoxResult Show(string messageBoxText, string caption);
    }

ثم لدينا الفصل الذي سيرث منه:

public class MessageBoxHelper : IMessageBox
    {
        /// <summary>Displays a message box that has a message, title bar caption, button, and icon; and that returns a result.</summary>            
        public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button,
            MessageBoxImage icon)
        {
            return MessageBox.Show(messageBoxText, caption, button, icon, MessageBoxResult.None,
                MessageBoxOptions.None);
        }

        /// <summary>Displays a message box that has a message, title bar caption, and button; and that returns a result.</summary>            
        public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button)
        {
            return MessageBox.Show(messageBoxText, caption, button, MessageBoxImage.None, MessageBoxResult.None,
                MessageBoxOptions.None);
        }

        /// <summary>Displays a message box that has a message and title bar caption; and that returns a result.</summary>            
        public MessageBoxResult Show(string messageBoxText, string caption)
        {
            return MessageBox.Show(messageBoxText, caption, MessageBoxButton.OK, MessageBoxImage.None,
                MessageBoxResult.None, MessageBoxOptions.None);
        }

        /// <summary>Displays a message box that has a message and that returns a result.</summary>           
        public MessageBoxResult Show(string messageBoxText)
        {
            return MessageBox.Show(messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None,
                MessageBoxResult.None, MessageBoxOptions.None);
        }
    }

الآن فقط استخدم هذا عند الحقن إلخ والازدهار، لديك تجريد واهية ستقوم بالخدعة ... وهي بخير اعتمادا على المكان الذي ستستخدمه. حالتي هي تطبيق بسيط يعني فقط القيام ببعض الأشياء، لذلك لا يوجد نقطة حول هندسة الحل. أمل أن هذا يساعد شخصاما.

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