MVVM-هل يجب أن يحتوي العرض على إشارة إلى المقدم/ViewModel؟

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

  •  07-07-2019
  •  | 
  •  

سؤال

لقد كنت أبحث في عينات PRISM 2 للحصول على أفكار حول أفضل طريقة للتعامل مع التطبيق الجديد الذي أعمل عليه، والذي سيكون تطبيق PRISM 2/WPF.وبالنظر بشكل خاص إلى تطبيق نموذج حقن العرض الذي يأتي مع PRISM، فقد لاحظت أن جميع طرق العرض تنفذ واجهة تسمح للمقدم (أو ViewModel) بالتفاعل مع طريقة العرض.

لقد فعلت ذلك في الماضي بالطريقة المعاكسة، حيث قمت بإدخال المقدم في العرض بحيث يمكن للعرض الاتصال مباشرة بالطرق الموجودة على المقدم مثل هذا قليلاً:

    public partial class SomeView : ModuleBase
    {

        private ISomePresenter _somePresenter;

        public SomeView (ISomePresenter somePresenter):this()
        {
            // Give the view a reference to the presenter
            _somePresenter = somePresenter;
            // Bind the View to the presenter
            DataContext = _somePresenter;
        }

    private void btnSubmit_Click(object sender, RoutedEventArgs e)
    {
        // The view can call actions directly on the presenter (OK I should probably use a command for this)
        _somePresenter.SomeAction();
    }
}

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

  • أضف المقدم إلى العرض واجعل العرض يتفاعل مع المقدم
  • قم بإضافة طريقة العرض إلى مقدم العرض واطلب من مقدم العرض التفاعل مع طريقة العرض
  • شيء مختلف تمامًا لم أفكر فيه بعد؟
هل كانت مفيدة؟

المحلول

أعتقد أن الأمر كله مسألة ذوق.أنا شخصياً أستمتع بالطريقة التي تراها في العينات التي تنظر إليها.لدى IView طريقة واحدة، وهي SetViewModel(...).يحتوي IViewModel على خاصية تسمى عرض نوع الكائن، والتي تقوم بشكل أساسي بإرجاع IView الذي تم إنشاء مثيل لـ DI.

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

للإجابة على السؤال، لا أحتاج بشكل عام إلى إشارة إلى مقدم العرض في Codebehind.عادةً ما يمكنني التعامل مع ذلك من خلال ربط الأوامر من العرض بجهاز VM.في بعض الحالات، قد ترغب في الاحتفاظ بمرجع للمقدم للقيام بما قمت به في المثال الخاص بك، ولكن يمكن تجنب ذلك نظرًا لمجموعة الأدوات الصحيحة (يجعل SL أكثر صعوبة لأنه لا يحتوي على أوامر مضمنة).

وكما قلت كلها مسألة ذوق..

-جير

نصائح أخرى

الطريقة الأكثر شيوعًا لتعيين ViewModel إلى طريقة عرض في MVVM هي استخدام ملف DataTemplate :

<DataTemplate DataType="{x:Type vm:SomeViewModel}">
    <v:SomeView />
</DataTemplate>

عندما تقوم بعرض مثيل ViewModel في ContentControl أو ItemsControl، سيقوم WPF تلقائيًا بإنشاء مثيل للعرض المناسب لـ ViewModel، وتعيين طريقة العرض DataContext إلى مثيل ViewModel.

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

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