Как создать прослушиватель действий представления для MvxItemTemplate

У меня есть представление, которое содержит 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?


person Paul Angevelle    schedule 17.10.2012    source источник


Ответы (1)


Я думаю, что простой способ сделать это - использовать настраиваемый «Просмотр» в элементе списка.

Примечание: здесь «представление» относится к представлениям Android, а не к представлениям Model-View-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);
            }
        }
    }
}

Затем вы можете использовать это представление в своем AXML так же, как вы используете представления Android или Mvx:

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

Альтернативный подход может состоять в том, чтобы как-то настроить список...

Если вам когда-нибудь потребуется полностью настроить представление списка и его адаптер, это можно легко сделать с помощью того же метода — наследования от 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
      ....
     />

to:

<Abv.MyListView
      ....
     />

Дополнительные примеры пользовательских представлений можно найти на GitHub — например. в некоторых проектах Calendar, ColorPicker, ActionBar в https://github.com/Cheesebaron

Не ожидайте, что ваши пользовательские элементы управления будут отображаться в дизайнере xamarin (ну, пока нет...)


Два заключительных замечания...

  1. Чтобы повторно использовать код... вы можете каким-то образом поместить эту функциональность HideSoftInputFromWindow в метод расширения, чтобы вы могли просто вызывать anyEditText.HideOnDone()

  2. Будьте осторожны при использовании событий Monodroid/monotouch в представлениях/UIViews — эти события, как правило, используют собственные делегаты/слушатели — и поэтому иногда вы можете обнаружить, что присоединение чего-то для подписки к одному событию может отсоединить что-то еще! Как правило, все в порядке, если вы не смешиваете и не сопоставляете подписки на события C# одновременно с собственными обработчиками прослушивателя/делегата.

person Stuart    schedule 17.10.2012
comment
большое спасибо ! Идеальный ответ имеет обычный. Я уже нашел и использую ViewNamespaceAbbreviations ;-) - person Paul Angevelle; 17.10.2012