如何为MvxItemTemplate创建视图的动作侦听器

时间:2012-10-17 12:47:15

标签: xamarin.android mvvmcross

我有一个包含MvxListView和表单的视图。我可以在视图的代码中使用以下代码隐藏软键盘(因为这是纯粹的视图问题)

var editText = FindViewById<EditText>(Resource.Id.newCheckbookName);
editText.EditorAction += (object sender, TextView.EditorActionEventArgs e) =>
    {
        if (e.ActionId == ImeAction.Done)
        {
            InputMethodManager inputMgr = GetSystemService(InputMethodService) as InputMethodManager;
            inputMgr.HideSoftInputFromWindow(CurrentFocus.WindowToken, 0);
        }
        return;
   };

在我的项目模板中,我有另一个文本编辑器,并希望具有相同的行为。但是我在哪里可以添加我的代码,因为我没有MwxItemTemplate的任何视图代码?

1 个答案:

答案 0 :(得分:2)

我认为这样做的简单方法是在listitem中使用自定义“View”。

注意:这里的“查看”是指Android视图 - 而不是模型 - 视图 - ViewModel视图 - 对于命名混淆感到抱歉!

创建自定义视图很容易......

只需创建一个自定义视图 - 例如

namespace Angevelle.App1.UI.Droid.Controls
{
    public class MyText : EditText
    {
        public MyText(Context context, IAttributeSet attrs)
            : base(context, attrs)
        {
            this.EditorAction += OnEditorAction;
        }

        private void OnEditorAction(object sender, EditorActionEventArgs editorActionEventArgs)
        {
            if (editorActionEventArgs.ActionId == ImeAction.Done)
            {
                // this code not tested - but something like this should work
                var imm = (InputMethodManager)Context.GetSystemService(Context.InputMethodService);
                imm.HideSoftInputFromWindow(WindowToken, 0);
            }
        }
    }
}

然后您可以像在Android或Mvx视图中一样在AXML中使用该视图:

<angevelle.app1.ui.droid.controls.MyText
         android:layout_height=....
     />

如果您发现angevelle.app1.ui.droid.controls过于冗长,那么您可以使用setup.cs中的缩写来缩短它:

    protected override IDictionary<string, string> ViewNamespaceAbbreviations
    {
        get
        {
            var abbreviations = base.ViewNamespaceAbbreviations;
            abbreviations["Abv"] = "angevelle.app1.ui.droid.controls";
            return abbreviations;
        }
    }

然后你可以使用:

<Abv.MyText
         android:layout_height=....
     />

另一种方法可能是以某种方式自定义列表......

如果你确实需要完全自定义listview及其适配器,那么可以使用相同类型的技术轻松完成 - 从UI项目中的MvxBindableListView继承:

public class MyListView : MvxBindableListView
{
        public MyListView(Context context, IAttributeSet attrs);
            : base(context, attrs, new MyListAdapter(context))
        {
        }
}

其中MyListAdapter覆盖视图创建:

public class MyListAdapter : MvxBindableListAdapter
{
    public MyListAdapter(Context context)
        : base(context)
    {
    }

    // put your custom Adapter code here... e.g.:
    protected override MvxBindableListItemView CreateBindableView(object source, int templateId)
    {
        return new MySpecialListItemView(_context, _bindingActivity, templateId, source);
    }
}

其中MySpecialListItemView继承自MvxBindableListItemView,但添加了您自己的自定义功能。

使用此方法,您的列表将从以下更改:

<Mvx.MvxBindableListView
      ....
     />

为:

<Abv.MyListView
      ....
     />

有关自定义视图的更多示例,请查看GitHub - 例如在https://github.com/Cheesebaron

中的某些Calendar,ColorPicker,ActionBar项目中

不要指望你的自定义控件在xamarin设计器中呈现(好吧,还没有...)


最后两个笔记......

  1. 要重复使用代码......您可能希望以某种方式将HideSoftInputFromWindow功能放在扩展方法中,以便只需调用anyEditText.HideOnDone()

  2. 在Views / UIViews上使用Monodroid / monotouch事件时要小心 - 这些事件倾向于使用本机委托/侦听器 - 因此有时您会发现附加某些内容以订阅一个事件可以取消其他内容!通常,只要您不与本机侦听器/委托处理程序同时混合和匹配C#事件订阅,就可以了。