Для того, чтобы привязка передать любое значение между видом на ViewModel, то нужно подключить в какое-то событие, когда изменяется значение.
В ViewModel это событие всегда является событием в интерфейсе INotifyProperty.
В представлении/действии используется один шаблон - поэтому каждое привязку должно подключаться к отдельному событию. Например, текст в EditText подключается с использованием события TextChanged (см. MvxEditTextTextTargetBinding.cs), а значение в SeekBar подключается с использованием объекта Listener, а не события (см. MvxSeekBarProgressTargetBinging.cs).
Так что если вы хотите, чтобы реализовать эту двустороннюю привязку для вашей деятельности, то вы могли бы сделать это:
- объявить событие - CurrentIndexChanged - в вашей деятельности (MyActivity), который вызывается при каждом изменении CurrentIndex
- объявить обязательный для MyActivity, который программно связывает CurrentIndex и CurrentIndexChanged
- добавления пользовательских привязки к связывающему реестру во время установки пользовательского
Например, ваша деятельность может включать в себя:
public event EventHandler CurrentIndexChanged;
private int _currentIndex;
public int CurrentIndex
{
get { return _currentIndex; }
set { _currentIndex = value; if (CurrentIndexChanged != null) CurrentIndexChanged(this, EventArgs.Empty); }
}
И вы могли бы затем объявить обязательный класс, как:
public class MyBinding : MvxPropertyInfoTargetBinding<MyActivity>
{
public MyBinding (object target, PropertyInfo targetPropertyInfo)
: base(target, targetPropertyInfo)
{
View.CurrentIndexChanged += OnCurrentIndexChanged;
}
public override MvxBindingMode DefaultMode
{
get
{
return MvxBindingMode.TwoWay;
}
}
private void OnCurrentIndexChanged(object sender, EventArgs ignored)
{
FireValueChanged(View.CurrentIndex);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
{
View.CurrentIndexChanged -= OnCurrentIndexChanged;
}
}
}
И вы должны сообщить системе связывания об этой привязке в настройках как :
registry.RegisterFactory(new MvxSimplePropertyInfoTargetBindingFactory(typeof(MyBinding), typeof(MyActivity), "CurrentIndex"));
Однако ... на практическом уровне, если вы работаете в C#, а не в XML, тогда вам может быть лучше в этом случае использовать C#, чтобы просто обновить ViewModel, а не использовать декларативное связывание в этом случае.
Чтобы был ясен ... в этом случае, я бы, скорее всего, просто написать свойство активности как:
public int CurrentIndex
{
get { return _currentIndex; }
set { _currentIndex = value; ViewModel.CurrentIndex = value; }
}
Или ... Я бы рассмотреть не обладающий это свойство в деятельности на всех.
Если это помогает, есть еще некоторая информация о пользовательских привязках в:
Надеется, что это помогает! ИМХО привязок там, чтобы помочь вам, когда вы работаете в XML - вы не должны использовать их ...
Стюарт
UPDATE Если вы собираетесь делать много эти и следует тому же шаблону имя - используя свойство с именем X с событием измененной EventHandler с именем XChanged то что-то подобное может работать - он использует отражение найти событие автомагический:
public class MyBinding<T> : MvxPropertyInfoTargetBinding<T>
where T : class
{
private readonly PropertyInfo _propertyInfo;
private readonly EventInfo _eventInfo;
public MyBinding(object target, PropertyInfo targetPropertyInfo)
: base(target, targetPropertyInfo)
{
_propertyInfo = targetPropertyInfo;
var eventName = _propertyInfo.Name + "Changed";
_eventInfo = View.GetType().GetEvent(eventName);
if (_eventInfo == null)
{
throw new MvxException("Event missing " + eventName);
}
if (_eventInfo.EventHandlerType != typeof(EventHandler))
{
throw new MvxException("Event type mismatch for " + eventName);
}
var addMethod = _eventInfo.GetAddMethod();
addMethod.Invoke(View, new object[] { new EventHandler(OnChanged) });
}
public override MvxBindingMode DefaultMode
{
get
{
return MvxBindingMode.TwoWay;
}
}
private void OnChanged(object sender, EventArgs ignored)
{
var value = _propertyInfo.GetValue(View, null);
FireValueChanged(value);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
{
var removeMethod = _eventInfo.GetRemoveMethod();
removeMethod.Invoke(View, new object[] { new EventHandler(OnChanged) });
}
}
}
@Stuart. В приведенном выше примере CurrentIndex является типом int, а MyBinding требует, чтобы T был ссылочным типом. Как использовать обновленный ответ? –
ttotto
@Stuart, реестр.RegisterFactory (новый MvxSimplePropertyInfoTargetBindingFactory (typeof (MyBinding), typeof (MyActivity), «CurrentIndex»)); Ошибка в MyBinding –
ttotto