2013-06-11 13 views
5

मैं रचना मेरे Android-अनुप्रयोग के लिए MvvmCross उपयोग कर रहा हूँ और मैं निम्नलिखित समस्या का सामना करना पड़ का उपयोग कर:दिखाएँ AlertDialog MvvmCross

जब मैं AlertDialog दिखाने के लिए कोशिश कर रहा हूँ, कि ViewModel में बनाया गया था,

"अनचाहे अपवाद: Android.Views.WindowManagerBadTokenException" प्रकट होता है।

public class MyViewModel : MvxViewModel 
{ 
    public ICommand ShowAlertCommand { get; private set; } 

    public AuthorizationViewModel() 
    { 
     ShowAlertCommand = new MvxCommand(() => 
      { 
       var adb = new AlertDialog.Builder(Application.Context); 
       adb.SetTitle("Title here"); 
       adb.SetMessage("Message here"); 
       adb.SetIcon(Resource.Drawable.Icon); 
       adb.SetPositiveButton("OK", (sender, args) => { /* some logic */}); 
       adb.SetNegativeButton("Cancel", (sender, args) => { /* close alertDialog */}); 

       adb.Create().Show(); 
      }); 
    } 
} 

जब मैं गया था researching मैं ने पाया है कि यह प्रसंग के संदर्भ के संचरण की वजह से लेकिन AlertDialog.Builder में गतिविधि पर नहीं होता है।

this topic में मैं निम्नलिखित निर्णय पाया: GetService() के उपयोग के माध्यम से वर्तमान गतिविधि के संदर्भ में प्राप्त है, लेकिन मैं IMvxServiceConsumer साथ काम करने के लिए mvvmcross प्लगइन्स, IMvxAndroidCurrentTopActivity इंटरफेस नहीं मिला था।

मेरा प्रश्न क्या मैं व्यूमोडेल से अलर्टडिअलॉग दिखा सकता हूं? और मैं गतिविधि का संदर्भ कैसे प्राप्त कर सकता हूं, लेकिन एप्लिकेशन के लिए नहीं। कॉन्टेक्स्ट? और अलर्टडिअलॉग को बंद करने का सही तरीका क्या है कि उपयोगकर्ता वर्तमान दृश्य पर रहेगा?

उत्तर

11

सामान्य तौर पर, आप ViewModels में कोड के इस प्रकार डाल करने के लिए नहीं की कोशिश करनी चाहिए

  • क्योंकि ViewModels मंच स्वतंत्र
  • क्योंकि ViewModels इकाई परीक्षण योग्य होना चाहिए रहना चाहिए - और यह इकाई परीक्षण करना मुश्किल है जब कोड पता चलता एक संवाद

मैं भी सलाह देते हैं कि आप एक ViewModel निर्माता के अंदर इस तरह कोड डाल नहीं है - इन निर्माताओं आम तौर पर नेविगेशन के दौरान कहा जाता है और एक संक्रमण के दौरान एक संवाद प्रदर्शित समस्या होने की संभावना है atic।


उन चीजों के साथ कहा, आप किसी भी कोड के भीतर मौजूदा शीर्ष गतिविधि की पकड़ पाने के लिए चाहते हैं, तो आप IMvxAndroidCurrentTopActivity

public interface IMvxAndroidCurrentTopActivity 
{ 
    Activity Activity { get; } 
} 

इस का उपयोग का उपयोग कर ऐसा कर सकते हैं, किसी भी कोड प्राप्त कर सकते हैं वर्तमान Activity का उपयोग कर:

var top = Mvx.Resolve<IMvxAndroidCurrentTopActivity>(); 
var act = top.Activity; 
if (act == null) 
{ 
    // this can happen during transitions 
    // - you need to be sure that this won't happen for your code 
    throw new MvxException("Cannot get current top activity"); 
} 

var dlg = new AlertDialog.Builder(act); 
//... 
dlg.Create().Show(); 

के उपयोग

  • मैं एक IFooDialog इंटरफ़ेस
  • आदर्श रूप में मैं पैदा करेगा: 8,383,210 में MvvmCross: How to pass Android context down to MvxCommand?

    दृष्टिकोण है कि प्रश्न में लिया चर्चा की है/उत्तर भी तरीके मैं आम तौर पर एक ViewModel से संवाद दिखा दृष्टिकोण हैं में से एक है शायद इस इंटरफेस को असीमित बना देगा - उदाहरण के लिएasync का उपयोग कर या एक मंच पर एक Action<DialogResult> कॉलबैक पैरामीटर

  • का उपयोग कर रहा लागू होता है कि यूआई परियोजना
  • ViewModel रों तो IFooDialog उपयोग कर सकते हैं जब एक संवाद की जरूरत है में और एक मंच के लिए एक उपयुक्त यूआई कार्रवाई के साथ प्रतिक्रिया कर सकते हैं

एमवीवीएम में यह 'संवाद सेवा' दृष्टिकोण सामान्य है - उदाहरण के लिए http://www.codeproject.com/Articles/36745/Showing-Dialogs-When-Using-the-MVVM-Pattern जैसे लेख देखें (हालांकि वह आलेख बहुत ही विंडोज़ विशिष्ट है!)

एमवीवीएमक्रॉस और संवादों के बारे में यहां कुछ अन्य प्रश्न भी हैं - हालांकि उनमें पुराने v1 या vNext कोड के संदर्भ हो सकते हैं - उदा। Alerts or Popups in MvvmCross और Unable run ProgressDialog - BadTokenException while showind

+0

ठीक है, मैं इस सामान :) –

+0

मैं कोशिश कर रहा हूँ का मानना ​​है कि वी एम से यूआई के साथ काम "फेंग शुई" नहीं है;), लेकिन Winphone और iPhone प्लेटफार्मों पहले से ही लांच कर रहे हैं, और मैं सिर्फ एंड्रॉयड की जरूरत मेरे आवेदन का संस्करण। भविष्य में, मेरी नई परियोजनाओं में, मैं आवश्यक रूप से कैनन एमवीवीएम के अनुसार विकसित होगा :) –

+0

स्टुअर्ट, 'IMvxAndroidCurrentTopActivity' के बारे में एक छोटा सा प्रश्न: क्या यह हमेशा एक ही उदाहरण होगा, भले ही वर्तमान शीर्ष गतिविधि में परिवर्तन हो? पृष्ठभूमि: मैं सेवा स्थान का प्रशंसक नहीं हूं, इसके बजाय मेरी कक्षाएं स्पष्ट निर्भरताएं लेती हैं। क्या यह काम करेगा यदि मेरे सिंगलटन क्लास में 'IMvxAndroidCurrentTopActivity' पर एक कन्स्ट्रक्टर निर्भरता है और यह अभी भी वर्तमान गतिविधि पर हमेशा काम कर सकता है? –