2013-08-29 56 views
1

在使用MvvmCross框架構建的跨平臺Xamarin應用程序中,我在Android .axml佈局中使用了ToggleButton Widget。我已使用轉換器使用以下綁定語法將Checked屬性綁定到View Model屬性:MvvmCross和UIButton.Selected UISegmentedControl綁定,iOS

Checked MarketBuySellViewModel.Direction, Converter=DirectionBool, ConverterParameter='Sell' 

一切正常。在iOS端,看起來你可以通過使用Selected屬性來使用UIButton作爲ToggleButton。這意味着下面的結合應該達到我想要iOS上的東西:

set.Bind (SellButton).For(b => b.Selected).To (vm => vm.MarketBuySellViewModel.Direction).WithConversion("DirectionBool", "Sell"); 

我沒有在應用程序的輸出得到任何約束力的錯誤,但似乎並結合本身不工作。單擊該按鈕不會設置Direction屬性,並將方向設置爲不同的值不會在UIButton上設置Selected屬性。

我需要創建一個自定義綁定還是我只是簡單地設置綁定?

我也嘗試使用UISegmentedControl來實現相同的效果。是否綁定到MvvmCross支持的此控件?我沒有在源代碼中看到它的任何引用。這是否意味着我需要爲它創建自定義綁定?

回答

1

對於UIButton,我不認爲在MvvmCross中內置了任何包含Selected的綁定。因爲這個 - 因爲Selected沒有簡單的配對事件SelectedChanged,那麼我認爲Selected綁定應該單向工作(從ViewModel到View)而不是雙向工作。

UISwitch控件的On有一個綁定,這是我在這些情況下使用最多的控件。


如果你想添加自定義2路爲Selected結合,然後我猜不得不這樣使用ValueChanged事件(但需要檢查是否是正確的)做的。

要做到這一點,你只是建立一個靶標結合類似:

public class MvxUIButtonSelectedTargetBinding : MvxPropertyInfoTargetBinding<UIButton> 
{ 
    public MvxUIButtonSelectedTargetBinding(object target, PropertyInfo targetPropertyInfo) 
     : base(target, targetPropertyInfo) 
    { 
     var view = View; 
     view.ValueChanged += HandleValueChanged; 
    } 

    private void HandleValueChanged(object sender, System.EventArgs e) 
    { 
     var view = View; 
     if (view == null) 
      return; 
     FireValueChanged(view.Selected); 
    } 

    public override MvxBindingMode DefaultMode 
    { 
     get { return MvxBindingMode.TwoWay; } 
    } 

    protected override void Dispose(bool isDisposing) 
    { 
     base.Dispose(isDisposing); 
     if (isDisposing) 
     { 
      var view = View; 
      if (view != null) 
      { 
       view.ValueChanged -= HandleValueChanged; 
      } 
     } 
    } 
} 

,這可能在安裝使用類似登記在protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)

registry.RegisterPropertyInfoBindingFactory(typeof(MvxUIButtonSelectedTargetBinding), typeof(UIButton), 
              "Selected"); 

同樣,我不相信任何人已經添加了雙向綁定UISegmentedControl - 但會愉快地看到一個添加。

建立一個雙向UISegmentedControl綁定將是相當直接的 - 你只需要綁定到SelectedSegmentValueChanged - 與上面類似的代碼。

或者,您可以切換到使用自定義MySegmentedControl它有一個更好的Value`ValueChanged`一對會不自定義綁定自動工作 - 例如:

public class MySegmentedControl : UISegmentedControl 
    { 
     // add more constructors if required 

     public int Value 
     { 
      get { return base.SelectedSegment; } 
      set { base.SelectedSegment = value; } 
     } 
    } 

如果任何或所有這些自定義綁定的需要,那麼MVX項目是高興得到這些綁定添加問題或https://github.com/slodge/MvvmCross-Tutorials/blob/master/ApiExamples/ApiExamples.Touch/Views/FirstView.cs項目,測試/演示的用戶界面拉請求一起

1

可能對別人有幫助,所以我分享了我的經驗。我需要一個雙向綁定UISegmentedControl.SelectedSegment屬性到ViewModel。單向標記(ViewModel => View)默認工作。我無法正確使用Stuart提出的解決方案 - 將UISegmentedControl進行子類化。我試圖確保鏈接器不會剝離新的自定義控件代碼,但這對我沒有幫助。因此,一個完美可行的解決方案就是使用MvxPropertyInfoTargetBinding的解決方案。這裏是代碼爲我工作好:

public class MvxUISegmentedControlSelectedSegmentTargetBinding : MvxPropertyInfoTargetBinding<UISegmentedControl> 
{ 
    public MvxUISegmentedControlSelectedSegmentTargetBinding(object target, PropertyInfo targetPropertyInfo) 
     : base(target, targetPropertyInfo) 
    { 
     this.View.ValueChanged += HandleValueChanged; 
    } 

    private void HandleValueChanged(object sender, System.EventArgs e) 
    { 
     var view = this.View; 
     if (view == null) 
     { 
      return; 
     } 
     FireValueChanged(view.SelectedSegment); 
    } 

    public override MvxBindingMode DefaultMode 
    { 
     get { return MvxBindingMode.TwoWay; } 
    } 

    protected override void Dispose(bool isDisposing) 
    { 
     base.Dispose(isDisposing); 
     if (isDisposing) 
     { 
      var view = this.View; 
      if (view != null) 
      { 
       view.ValueChanged -= HandleValueChanged; 
      } 
     } 
    } 
} 

public class Setup : MvxTouchSetup 
{ 
    ... 
    protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry) 
    { 
     registry.RegisterPropertyInfoBindingFactory(typeof(MvxUISegmentedControlSelectedSegmentTargetBinding), typeof(UISegmentedControl), "SelectedSegment"); 
    } 
}