android–MVVMCross在MvxBindableListView中更改ViewModel

android–MVVMCross在MvxBindableListView中更改ViewModel,第1张

概述我的Android应用程序的问题很小,我不知道如何使用MVVMCross解决它.这是我的模特publicclassArticle{stringLabel{get;set;}stringRemark{get;set;}}我的ViewModelpublicclassArticleViewModel:MvxViewModel{publicList<Article>Article

我的Android应用程序的问题很小,我不知道如何使用MVVM Cross解决它.

这是我的模特

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”的“Click”命令链接在MvxBindableListVIEw给出的项目上.换句话说,单击在我的模型“文章”中搜索命令“MyTest”,而不是我的viewmodel.如何更改该行为以链接我的viewmodel“Articleviewmodel”,它负责我的MvxBindableListVIEw?

有什么建议?

解决方法:

您的分析对于click事件尝试绑定的位置肯定是正确的.

我通常采用两种方法:

>在列表上使用ItemClick
>继续使用Click但在viewmodel端进行一些重定向.

所以…… 1

本教程中的Main Menu有一个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中用作:

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

这种方法只能对整个列表项中的ItemClick进行 – 而不是对列表项中的单个子视图进行.

还是… 2

由于我们在mvx中没有任何relativeSource绑定指令,因此可以在viewmodel / Model代码中完成此类重定向.

这可以通过呈现Model对象的行为启用包装器而不是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'}}" />

这种方法的一个例子是使用WithCommand的会议样本

但请注意,使用WithCommand< T>时我们发现内存泄漏 – 基本上GarbageCollection拒绝收集嵌入式MvxRelayCommand – 这就是为什么WithCommand< T>是Idisposable,为什么BaseSessionListViewModel清除列表并在分离视图时处理WithCommand元素.

评论后更新:

如果您的数据列表很大 – 并且您的数据是固定的(您的文章是没有PropertyChanged的模型),并且您不希望产生创建大型List< WrappedArticle>的开销.那么解决这个问题的一种方法可能是使用WrapPingList< T>类.

这与Microsoft代码中采用的方法非常相似 – 例如在WP7 / Silverlight – 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}   
总结

以上是内存溢出为你收集整理的android – MVVMCross在MvxBindableListView中更改ViewModel全部内容,希望文章能够帮你解决android – MVVMCross在MvxBindableListView中更改ViewModel所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1103400.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存