2012-10-01 30 views
7

के भीतर ViewModel को बदल रहा है मेरे एंड्रॉइड एप्लिकेशन के साथ छोटी समस्या और मुझे नहीं पता कि एमवीवीएम क्रॉस के साथ इसे कैसे हल किया जाए।MVVMCross एक MvxBindableListView

यहाँ मेरी मॉडल है

public class Article 
{ 
    string Label{ get; set; } 
    string Remark { get; set; } 
} 

मेरे ViewModel

public class ArticleViewModel: MvxViewModel 
{ 
    public List<Article> Articles; 
    .... 

} 

मेरे layout.axml ...

<LinearLayout 
     android:layout_width="0dip" 
     android:layout_weight="6" 
     android:layout_height="fill_parent" 
     android:orientation="vertical" 
     android:id="@+id/layoutArticleList"> 
     <EditText 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:id="@+id/editSearch" 
      android:text="" 
      android:singleLine="True" 
      android:selectAllOnFocus="true" 
      android:capitalize="characters" 
      android:drawableLeft="@drawable/ic_search_24" 
      local:MvxBind="{'Text':{'Path':'Filter','Mode':'TwoWay'}}" 
      /> 
     <Mvx.MvxBindableListView 
      android:id="@+id/listviewArticle" 
      android:choiceMode="singleChoice" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:orientation="vertical" 
      local:MvxItemTemplate="@layout/article_rowlayout" 
      local:MvxBind="{'ItemsSource':{'Path':'Articles'}}" />     
    </LinearLayout> 
... 

और यहाँ आता है मेरी समस्या, "article_rowlayout"

... 
<TableRow 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@color/blue"> 
     <TextView 
      android:id="@+id/rowArticleLabel" 
      android:layout_width="0dip" 
      android:layout_weight="14" 
      android:layout_height="wrap_content" 
      android:textSize="28dip" 
      local:MvxBind="{'Text':{'Path':'Label'}}" /> 
     <ImageButton 
      android:src="@drawable/ic_modify" 
      android:layout_width="0dip" 
      android:layout_weight="1" 
      android:layout_height="wrap_content" 
      android:id="@+id/rowArticleButtonModify" 
      android:background="@null" 
      android:focusable="false" 
      android:clickable="true"  
      local:MvxBind="{'Click':{'Path':'MyTest'}}" 
      /> 
... 

"MyTest" नामक "क्लिक" कमांड MVxBindableListView द्वारा दिए गए आइटम पर लिंक किया गया है। दूसरे शब्दों में, मेरे ViewModel के बजाय, मेरे मॉडल "आलेख" में "MyTest" कमांड के लिए खोज पर क्लिक करें। मेरे व्यूमोडेल "ArticleViewModel" को लिंक करने के लिए मैं उस व्यवहार को कैसे बदल सकता हूं जो मेरे एमवीएक्सबिंडबल लिस्ट व्यू के लिए ज़िम्मेदार है?

कोई सुझाव?

उत्तर

7

आपका विश्लेषण निश्चित रूप से सही है कि क्लिक ईवेंट कहां बांधने की कोशिश कर रहा है, इसके बारे में निश्चित रूप से सही है। सूची

  • क्लिक करें का उपयोग कर, लेकिन ViewModel तरफ कुछ पुनर्निर्देशन करना जारी रखते हुए पर

    1. उपयोग ItemClick:

      दो दृष्टिकोण मैं आम तौर पर ले रहे हैं।


    तो ... 1

    ट्यूटोरियल में Main Menu है एक ViewModel एक सा की तरह:

    <Mvx.MvxBindableListView 
        xmlns:android="http://schemas.android.com/apk/res/android" 
        xmlns:local="http://schemas.android.com/apk/res/Tutorial.UI.Droid" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        local:MvxBind="{'ItemsSource':{'Path':'Items'},'ItemClick':{'Path':'ShowItemCommand'}}" 
        local:MvxItemTemplate="@layout/listitem_viewmodel" 
        /> 
    
    :

    public class MainMenuViewModel 
        : MvxViewModel 
    { 
        public List<T> Items { get; set; } 
    
        public IMvxCommand ShowItemCommand 
        { 
         get 
         { 
          return new MvxRelayCommand<T>((item) => /* do action with item */); 
         } 
        } 
    } 
    

    इस रूप में axml में प्रयोग किया जाता है

    यह दृष्टिकोण केवल संपूर्ण सूची आइटम पर आइटमक्लिक के लिए किया जा सकता है - नहीं सूची वस्तुओं के भीतर व्यक्तिगत सबव्यू पर।


    या ... 2

    जब से हम mvx में किसी भी RelativeSource बाध्यकारी निर्देश की जरूरत नहीं है, पुनर्निर्देशन के इस प्रकार ViewModel/मॉडल कोड में किया जा सकता।

    यह मॉडल ऑब्जेक्ट के बजाए मॉडल ऑब्जेक्ट के व्यवहार-सक्षम रैपर को प्रस्तुत करके किया जा सकता है - उदा।का उपयोग कर एक List<ActiveArticle>:

    public ActiveArticle 
    { 
        Article _article; 
        ArticleViewModel _parent; 
    
        public WrappedArticle(Article article, ArticleViewModel parent) 
        { 
         /* assignment */ 
        } 
    
        public IMvxCommand TheCommand { get { return MvxRelayCommand(() -> _parent.DoStuff(_article)); } } 
    
        public Article TheArticle { get { return _article; } } 
    } 
    

    आपका axml तो जैसे बाइंडिंग का उपयोग करने के लिए होगा:

    और इस दृष्टिकोण का

    <ImageButton 
         ... 
         local:MvxBind="{'Click':{'Path':'TheCommand.MyTest'}}" /> 
    

    एक उदाहरण सम्मेलन नमूना जो WithCommand

    का उपयोग करता है

    हालांकि ... कृपया ध्यान दें किका उपयोग करते समयहमने एक स्मृति रिसाव की खोज की - मूल रूप से कचरा कोलेक्शन ने एम्बेडेड MvxRelayCommand एकत्र करने से इंकार कर दिया - यही कारण है कि WithCommand<T>IDisposable है और क्यों BaseSessionListViewModel सूची साफ़ करता है और विचारों को अलग करते समय WithCommand तत्वों का निपटान करता है।


    अद्यतन टिप्पणी के बाद:

    अपने डेटा सूची बड़ा है, तो - और अपने डेटा ठीक हो गई है (अपने लेख PropertyChanged बिना मॉडल हैं) और आप एक बनाने की भूमि के ऊपर उठाना नहीं करना चाहते बड़े List<WrappedArticle> तो इसके आसपास एक तरीका WrappingList<T> वर्ग का उपयोग करना हो सकता है।

    यह माइक्रोसॉफ्ट कोड में किए गए दृष्टिकोण के समान है - उदा। WP7/सिल्वरलाइट में सूचियों virtualizing में - http://shawnoster.com/blog/post/Improving-ListBox-Performance-in-Silverlight-for-Windows-Phone-7-Data-Virtualization.aspx

    अपने लेख के लिए यह हो सकता है:

    public class ArticleViewModel: MvxViewModel 
    { 
        public WrappingList<Article> Articles; 
    
        // normal members... 
    } 
    
    public class Article 
    { 
        public string Label { get; set; } 
        public string Remark { get; set; } 
    } 
    
    public class WrappingList<T> : IList<WrappingList<T>.Wrapped> 
    { 
        public class Wrapped 
        { 
         public IMvxCommand Command1 { get; set; } 
         public IMvxCommand Command2 { get; set; } 
         public IMvxCommand Command3 { get; set; } 
         public IMvxCommand Command4 { get; set; } 
         public T TheItem { get; set; } 
        } 
    
        private readonly List<T> _realList; 
        private readonly Action<T>[] _realAction1; 
        private readonly Action<T>[] _realAction2; 
        private readonly Action<T>[] _realAction3; 
        private readonly Action<T>[] _realAction4; 
    
        public WrappingList(List<T> realList, Action<T> realAction) 
        { 
         _realList = realList; 
         _realAction = realAction; 
        } 
    
        private Wrapped Wrap(T item) 
        { 
         return new Wrapped() 
          { 
           Command1 = new MvxRelayCommand(() => _realAction1(item)), 
           Command2 = new MvxRelayCommand(() => _realAction2(item)), 
           Command3 = new MvxRelayCommand(() => _realAction3(item)), 
           Command4 = new MvxRelayCommand(() => _realAction4(item)), 
           TheItem = item 
          }; 
        } 
    
        #region Implementation of Key required methods 
    
        public int Count { get { return _realList.Count; } } 
    
        public Wrapped this[int index] 
        { 
         get { return Wrap(_realList[index]); } 
         set { throw new NotImplementedException(); } 
        } 
    
        #endregion 
    
        #region NonImplementation of other methods 
    
        public IEnumerator<Wrapped> GetEnumerator() 
        { 
         throw new NotImplementedException(); 
        } 
    
        IEnumerator IEnumerable.GetEnumerator() 
        { 
         return GetEnumerator(); 
        } 
    
        public void Add(Wrapped item) 
        { 
         throw new NotImplementedException(); 
        } 
    
        public void Clear() 
        { 
         throw new NotImplementedException(); 
        } 
    
        public bool Contains(Wrapped item) 
        { 
         throw new NotImplementedException(); 
        } 
    
        public void CopyTo(Wrapped[] array, int arrayIndex) 
        { 
         throw new NotImplementedException(); 
        } 
    
        public bool Remove(Wrapped item) 
        { 
         throw new NotImplementedException(); 
        } 
    
        public bool IsReadOnly { get; private set; } 
    
        #endregion 
    
        #region Implementation of IList<DateFilter> 
    
        public int IndexOf(Wrapped item) 
        { 
         throw new NotImplementedException(); 
        } 
    
        public void Insert(int index, Wrapped item) 
        { 
         throw new NotImplementedException(); 
        } 
    
        public void RemoveAt(int index) 
        { 
         throw new NotImplementedException(); 
        } 
    
        #endregion 
    } 
    
  • +0

    वास्तव में, मैं अपने सूचीदृश्य पर व्यवहार के साथ 4 imagebuttons है। तो पहला समाधान असंभव है। दूसरी बात के लिए, मेरी समस्या यह है कि मैं अपनी सूची किसी अन्य ढांचे (vici coolstorage) से बताता हूं, और "सक्रिय आर्टिकल" के साथ एक नया निर्माण करने के लिए पूरी सूची को पार्स करने से गंभीर ओवरहेड (मेरे पास कई हजार आइटम हो सकते हैं)। लेकिन वैसे भी, मैं इस समाधान का प्रयास करूंगा और आपको यह बताएगा कि यह काम करता है या नहीं। वैसे, आपको नहीं लगता कि आपके ढांचे पर "सापेक्ष स्रोत" बनाना मुश्किल होगा? धन्यवाद! – hugoterelle

    +0

    ने आपके लिए कोई विकल्प जोड़ा है - उत्तर में अपडेट देखें। "वैसे, आपको नहीं लगता कि यह मुश्किल होगा" इसे सभी प्लेटफार्मों पर रिश्तेदार संसाधन की पहचान करने के किसी तरीके की आवश्यकता होगी (उदाहरण के लिए इसे Droid में पैरेंट पदानुक्रम नेविगेट करने का कुछ तरीका उपयोग करना पड़ सकता है) और फिर संपत्ति की पहचान करना बाध्य करने के लिए (Droid मूल दृश्य के पास सुविधाजनक डेटाकॉन्टेक्स्ट निर्भरता ऑब्जेक्ट नहीं है)। यह संभव हो सकता है - यह देखने में आपकी दिलचस्पी होगी कि आप क्या चाहते हैं - अपने आदर्श अक्षीय समाधान को गिटब/स्लॉज/एमवीवीएमक्रॉस – Stuart

    +0

    हाय स्टुअर्ट में किसी समस्या के रूप में दिखने के लिए स्वतंत्र महसूस करें, आपका नया समाधान मेरे लिए समाधान है। बहुत बहुत धन्यवाद। मैंने अपना समाधान अपने कोड में रखा है, और मैं जिथब में एक समस्या के रूप में "आदर्श धुरी दृष्टि" (मेरे लिए) डालूंगा। फिर से धन्यवाद, आप महान हैं! – hugoterelle