爲了使結合到View之間傳送的任何值到一個ViewModel,那麼它需要掛接到某個事件的值的變化時。
在ViewModel中,此事件始終是INotifyProperty接口中的事件。
在視圖/活動中,使用了一個單一模式 - 因此每個綁定必須掛鉤到單獨的事件中。例如,使用TextChanged事件(參見MvxEditTextTextTargetBinding.cs)連接EditText上的文本,而使用Listener對象而不是事件(請參閱MvxSeekBarProgressTargetBinging.cs)將SeekBar中的值連接起來。
所以,如果你想實現這種雙向爲您的活動結合,那麼你可以通過這樣做:
- 聲明一個事件 - 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命名的屬性與名爲改變事件處理事件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(new MvxSimplePropertyInfoTargetBindingFactory(typeof(MyBinding),typeof(MyActivity),「CurrentIndex」)); MyBinding錯誤 –
ttotto