复选框单击事件处理程序称为两次

时间:2015-02-27 04:34:52

标签: xamarin xamarin.android

出于某种原因,我的Checkbox.Click事件处理程序在我的Xamarin.Android的自定义ListView适配器中被调用两次。我正在提供我的GetView方法,以获取我做错的任何帮助或指针。

public override View GetView(int position, View convertView, ViewGroup parent)
        {
            ServiceViewHolder holder = null;
            var view = convertView;

            if (view == null)
            {
                view = Context.LayoutInflater.Inflate(Resource.Layout.ListRowService, null);

                holder = new ServiceViewHolder
                {
                    Name = view.FindViewById<TextView>(Resource.Id.tvServiceName),
                    Price = view.FindViewById<TextView>(Resource.Id.tvServicePrice),
                    SelectCheckbox = view.FindViewById<CheckBox>(Resource.Id.checkboxAdd)                    
                };

                view.Tag = holder;
            }
            else
            {
                    holder = view.Tag as ServiceViewHolder;
            }

            var tempServiceItem = ServiceItems[position];
            holder.Name.Text = tempServiceItem.Name;            
            holder.SelectCheckbox.Click += (o, e) =>
            {
                if (holder.SelectCheckbox.Checked)
                {
                    var myActivity = (ServicesListActivity) Context;
                    myActivity.OnServiceSelected(tempServiceItem, true);
                }
                else
                {
                    var myActivity = (ServicesListActivity) Context;
                    myActivity.OnServiceSelected(tempServiceItem, false);
                }
            };
            return view;
        }

       private class ServiceViewHolder : Java.Lang.Object
        {
            public TextView Name { get; set; }
            public TextView Price { get; set; }
            public CheckBox SelectCheckbox { get; set; }
        }

只是为了澄清一下,这个Checkbox.Click事件处理程序的目标是将选定的项目传递给Activity,但它会在第一次点击后再次为每次点击调用自己。

2 个答案:

答案 0 :(得分:1)

您确定只调用一次GetView吗?如果没有,则click事件绑定将堆叠。移动click事件绑定或确保其仅绑定一次。

public override View GetView(int position, View convertView, ViewGroup parent)
    {
        ServiceViewHolder holder = null;
        var view = convertView;

        if (view == null)
        {
            view = Context.LayoutInflater.Inflate(Resource.Layout.ListRowService, null);

            holder = new ServiceViewHolder
            {
                Name = view.FindViewById<TextView>(Resource.Id.tvServiceName),
                Price = view.FindViewById<TextView>(Resource.Id.tvServicePrice),
                SelectCheckbox = view.FindViewById<CheckBox>(Resource.Id.checkboxAdd)                    
            };

            view.Tag = holder;
            holder.SelectCheckbox.Tag = holder;

            holder.SelectCheckbox.Click += (o, e) =>
            {
                var h = (ServiceViewHolder)((CheckBox)o).Tag;
                var tempServiceItem = ServiceItems[h.Position];
                h.Name.Text = tempServiceItem.Name;

                if (h.SelectCheckbox.Checked)
                {
                    var myActivity = (ServicesListActivity) Context;
                    myActivity.OnServiceSelected(tempServiceItem, true);
                }
                else
                {
                   var myActivity = (ServicesListActivity) Context;
                   myActivity.OnServiceSelected(tempServiceItem, false);
                }
            };
        }
        else
        {
                holder = (ServiceViewHolder)view.Tag;
        }

        holder.Position = position;


        return view;
    }

   private class ServiceViewHolder : Java.Lang.Object
    {
        public TextView Name { get; set; }
        public TextView Price { get; set; }
        public CheckBox SelectCheckbox { get; set; }
        publit int Position{get;set;}
    }

答案 1 :(得分:0)

根据这个Xamarin论坛帖http://forums.xamarin.com/discussion/comment/27030/#Comment_27030我意识到我两次调用Checkbox事件处理程序,所以我重新考虑它只被调用一次。

if (convertView == null)
            {
               convertView = Context.LayoutInflater.Inflate(Resource.Layout.ListRowService, null);

                holder = new ServiceViewHolder
                {
                    Name = convertView.FindViewById<TextView>(Resource.Id.tvServiceName),
                    Price = convertView.FindViewById<TextView>(Resource.Id.tvServicePrice),
                    Category = convertView.FindViewById<TextView>(Resource.Id.tvServiceCategory),
                    EditButton = convertView.FindViewById<ImageButton>(Resource.Id.buttonEditService),
                    DeleteButton = convertView.FindViewById<ImageButton>(Resource.Id.buttonDeleteService),
                    SelectCheckbox = convertView.FindViewById<CheckBox>(Resource.Id.checkboxAdd)

                };

                holder.SelectCheckbox.Click += (o, e) => mFragment.OnServiceSelected(tempServiceItem, holder.SelectCheckbox.Checked);

                convertView.Tag = holder;
            }
            else
            {
                holder = (ServiceViewHolder)convertView.Tag;
            }

            //var tempServiceItem = new ServiceItem();
            holder.Name.Text = tempServiceItem.Name;
            holder.Category.Text = tempServiceItem.Category;
            holder.Price.Text = String.Format("{0:C}", tempServiceItem.Price);
            holder.DeleteButton.Click += (object sender, EventArgs e) =>
            {
                ServiceItems.Remove(tempServiceItem);
                ServicesManager.DeleteServiceItem(tempServiceItem.Id);

                //Then refresh the screen to show the item has been removed
                NotifyDataSetChanged();

            };
            holder.EditButton.Click += (object sender, EventArgs e) =>
            {

            };