Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
183 views
in Technique[技术] by (71.8m points)

c# - Binding button click in ListView template MvvMCross

I have a listview with a template containing a button. When the button get's clicked i want an event to fire and return me a value of the listview row, so i can use it to add it to a database. My problem is, i don't know how to bind my buttonevent to the itemtemplate. I've tried a few approaches but with no success so far.

My Listview:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:local="http://schemas.android.com/apk/res-auto"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent">

    <Mvx.MvxListView

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:divider="#aeaeae"

        android:dividerHeight="1px"

        local:MvxBind="ItemsSource MenuCollection; ItemClick OrderBtnClick"        

        local:MvxItemTemplate="@layout/listitem_menuitem" />

</LinearLayout>

My ItemTemplate:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:local="http://schemas.android.com/apk/res-auto"

    android:orientation="horizontal"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent">

    <Mvx.MvxImageView

        android:layout_width="100dp"

        android:layout_height="100dp"

        android:layout_margin="10dp"

        local:MvxBind="ImageUrl ImageUrl" />

    <LinearLayout

        android:orientation="vertical"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:layout_weight="1">

        <TextView

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:layout_marginLeft="30dp"

            android:textSize="40dp"

            local:MvxBind="Text Name" />

        <TextView

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:layout_marginLeft="50dp"

            android:textSize="20dp"

            local:MvxBind="Text ShortDescription" />

    </LinearLayout>

    <LinearLayout

        android:orientation="vertical"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:layout_weight="1"

        android:minWidth="25px"

        android:minHeight="25px">

        <Button

            android:layout_width="wrap_content"

            android:layout_height="70dip"

            android:layout_alignParentRight="true"

            android:layout_marginTop="20dip"

            android:layout_marginRight="20dip"

            android:layout_gravity="right|center_vertical"

            android:text="Bestel"            

            android:id="@+id/button1" />

    </LinearLayout>

</LinearLayout>

My ViewModel:

public class ListPresentationViewModel: MvxViewModel    
    {    
        private readonly ISQLService _sqlSvc;   

        public ListPresentationViewModel (ISQLService sqlService)    
        {    
            _sqlSvc = sqlService;    
            MenuCollection = _sqlSvc.MenuItemGetAll ();    
        }   


        private List<MenuItem> _menuCollection = new List<MenuItem> ();    

        public List<MenuItem> MenuCollection {    
            get{ return _menuCollection;}    
            set {    
                _menuCollection = value;
                RaisePropertyChanged (() => MenuCollection);    
            }    
        }    


        private IMvxCommand _orderBtnClick;    
        public IMvxCommand OrderBtnClick{    
            get{    
                _orderBtnClick = _orderBtnClick ?? new MvxCommand(btnClick);

                return _orderBtnClick;}    

        }  


        private void btnClick()    
        {    
            //Do Something    
        }

    }

I placed the local:MvxBind="Click OrderBtnClick" on the button in the template and on the listview. The ItemClick seems to work when i remove the button from the itemtemplate, but that's not what i'm looking for. I want the button to be triggering the event. Can anyone point me in the right direction?


UPDATE:

I've tried the second suggestion stuart lodge posted here. Here is my wrapper class:

public class MenuItemWrap
    {
        MenuItem _mnuItem;
        ListPresentationViewModel _parent;


        public MenuItemWrap ()
        {           

        }

        public MenuItemWrap (MenuItem item, ListPresentationViewModel parent)
        {
            _mnuItem = item;
            _parent = parent;
        }

        public IMvxCommand Click {
            get {
                return new MvxRelayCommand (() => _parent.btnClick(WrapConverter.ConvertToWrapMenuItem(_mnuItem, _parent)));
            }
        }
        public MenuItem Item{ get { return _mnuItem; } }

    }

My ViewModel:

public class ListPresentationViewModel: MvxViewModel
    {
        private readonly ISQLService _sqlSvc;

        public ListPresentationViewModel (ISQLService sqlService)
        {
            _sqlSvc = sqlService;
            MenuCollection = WrapConverter.ConvertToWrapperClass(_sqlSvc.MenuItemGetAll (), this);
        }

        private List<MenuItemWrap> _menuCollection = new List<MenuItemWrap> ();
        public List<MenuItemWrap> MenuCollection {
            get{ return _menuCollection;}
            set {
                _menuCollection = value;
                RaisePropertyChanged (() => MenuCollection);
            }
        }

        private IMvxCommand _orderBtnClick;
        public IMvxCommand OrderBtnClick{
            get{
                _orderBtnClick = _orderBtnClick ?? new MvxCommand<MenuItemWrap> (btnClick);
                return _orderBtnClick;
            }
        }

        public void btnClick(MenuItemWrap item)
        {
            MenuCollection.Clear ();
        }
    }

And here is my template:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:local="http://schemas.android.com/apk/res-auto"

    android:orientation="horizontal"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent">

    <Mvx.MvxImageView

        android:layout_width="100dp"

        android:layout_height="100dp"

        android:layout_margin="10dp"

        local:MvxBind="ImageUrl Item.ImageUrl" />

    <LinearLayout

        android:orientation="vertical"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:layout_weight="1">

        <TextView

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:layout_marginLeft="30dp"

            android:textSize="40dp"

            local:MvxBind="Text Item.Name" />

        <TextView

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:layout_marginLeft="50dp"

            android:textSize="20dp"

            local:MvxBind="Text Item.ShortDescription" />

    </LinearLayout>

    <LinearLayout

        android:orientation="vertical"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:layout_weight="1"

        android:minWidth="25px"

        android:minHeight="25px">

        <Button

            android:layout_width="wrap_content"

            android:layout_height="70dip"

            android:layout_alignParentRight="true"

            android:layout_marginTop="20dip"

            android:layout_marginRight="20dip"

            android:layout_gravity="right|center_vertical"

            android:text="Bestel"

            local:MvxBind="Click btnClick.OrderBtnClick"

            android:id="@+id/button1" />

    </LinearLayout>

</LinearLayout>

My listview works perfectly. All properties get bind correctly, and i can see the name, shortdescription and image. What does not work is the Button Click. In my application output i get an error saying: MvxBind:Warning: 76.06 Unable to bind: source property source not found Cirrious.MvvmCross.Binding.Parse.PropertyPath.PropertyTokens.MvxPropertyNamePropertyToken on MenuItemWrap

I've tried a few approaches to fix it, but with no success. I will mention i did not find the RelayCommand class in the MvvMCross assemblies so i copy pasted the code from here into my project.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've found the solution. The problem was the click binding. You should only refer to the action in the wrapper class and not both. Here are my wrapperclass & listview itemtemplate.

ItemTemplate:

 <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:minWidth="25px"
            android:minHeight="25px">
            <Button
                android:layout_width="wrap_content"
                android:layout_height="70dip"
                android:layout_alignParentRight="true"
                android:layout_marginTop="20dip"
                android:layout_marginRight="20dip"
                android:layout_gravity="right|center_vertical"
                android:text="Bestel"
                local:MvxBind="Click OrderClick" />
        </LinearLayout>

WrapperClass:

public class MenuItemWrap
    {
        MenuItem _mnuItem;
        ListPresentationViewModel _parent;      

        public MenuItemWrap (MenuItem item, ListPresentationViewModel parent)
        {
            _mnuItem = item;
            _parent = parent;
        }


        public IMvxCommand OrderClick {
            get {
                return new MvxCommand (() => _parent.btnClick (_mnuItem));
            }
        }

        public MenuItem Item{ get { return _mnuItem; } }    
    }

My ViewModel:

public class ListPresentationViewModel: MvxViewModel 
{
    private readonly ISQLService _sqlSvc;

    public ListPresentationViewModel (ISQLService sqlService)
    {
        _sqlSvc = sqlService;
        MenuCollection = WrapConverter.ConvertToWrapperClass (_sqlSvc.MenuItemGetAll(), this);
    }

    private int _catId;
    public int CategorieId { 
        get{ return _catId;} 
        set{ 
            _catId = value;
            ChangeMenuCollection ();
        }
    }

    private void ChangeMenuCollection()
    {
        MenuCollection = WrapConverter.ConvertToWrapperClass (_sqlSvc.MenuItemByCategorie (_catId), this);
    }

    private List<MenuItemWrap> _menuCollection = new List<MenuItemWrap> ();
    public List<MenuItemWrap> MenuCollection {
        get{ return _menuCollection;}
        set {
            _menuCollection = value;
            RaisePropertyChanged (() => MenuCollection);
        }
    }

    private IMvxCommand _orderBtnClick;

    public IMvxCommand OrderBtnClick {
        get {
            _orderBtnClick = _orderBtnClick ?? new MvxCommand<MenuItem> (btnClick);
            return _orderBtnClick;
        }
    }

    public void btnClick (MenuItem item)
    {
        //Do Something
    }
}       

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...