質問

Androidアプリケーションのほとんど問題で、私はMVVMクロスでそれを解決する方法がわかりません。

これは私のモデルです

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>
...
.

そしてここに私の問題があり、 "Artical_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"という "Click"コマンドは、MVxBindablEListViewによって指定された項目にリンクされています。つまり、ViewModelではなく、My Model "記事"のコマンド "mytest"の検索をクリックします。MVXBindablEListViewを担当するMy ViewModelの "ArticalViewModel"をリンクするために、その動作を変更するにはどうすればよいですか?

任意の提案?

役に立ちましたか?

解決

あなたの分析は、クリックイベントがバインドしようとしている場所について間違いなく正しいです。

一般的に2つのアプローチがあります:

  1. list の項目を使う
  2. クリックを継続して、ビューモデルサイドにリダイレクトを実行します。

    だから... 1

    チュートリアルのメインメニュービューモーデルがビットモーデルを持っています。

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

    これはAXMLで使用されています。

    <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"
      />
    
    .

    このアプローチは、リスト項目全体での項目Clickでのみ行うことができます - リスト項目内の個々のサブビューではありません。


    または... 2

    MVXにRelativeSourceバインディング命令がありませんので、このタイプのリダイレクトはViewModel / Modelコードで行うことができます。

    これは、モデルオブジェクト自体ではなく、モデルオブジェクトの動作対応のラッパーを提示することによって行うことができます。 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は、次のようなバインディングを使用する必要があります。

        <TextView            ...
            local:MvxBind="{'Text':{'Path':'TheArticle.Label'}}" />
    
    .

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

    このアプローチの一例は、 withコマンド

    しかしながら、WithCommand<T>を使用する場合、メモリリークを発見した場合 - 基本的にGarbageCollectionが埋め込まれたMvxRelayCommandの収集を拒否しました。スロッジ/ mvvmcross / blob / master / sample / sample.curious.confore.core.core / beabeSessionListViewModel.cs "rel=" noreferrer "> basesessionListViewModel ビューのときにIntemMand要素を解除します。切り離されています。


    コメント後の更新:

    データリストが大きい場合 - あなたのデータが修正されています(あなたの記事はPropertyChangedのないモデルです)、大きなWithCommand<T>を作成するオーバーヘッドを獲得したくない場合は、これを回避する1つの方法はIDisposableクラスを使用することです。 。

    これは、Microsoftコードで取られたアプローチと非常によく似ています。 WP7 / Silverlightの仮想化リストで - http://shawnoster.com/blog/post/improving-ListBox-performance-in-Silverlight-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
    }   
    
    .

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top