2016-08-22 10 views
0

私は、iOSアプリケーションでネットワーク接続をチェックしていて、ビューモデルのビューコントローラでboolean hasNetworkConnectionをバインドしようとしているという問題があります。私は自分のiOS固有のコードを使用して接続性をチェックし、ブール値をバインドしたいMVVMとの双方向バインド

ビューコントローラUpdateContentView.cs

// This file has been autogenerated from a class added in the UI designer. 

using System; 
using MvvmCross.iOS.Views; 
using MvvmCross.Binding.BindingContext; 
using Training.Core; 

namespace EdwardsTraining.IOS 
{ 
    public partial class UpdateContentView : MvxViewController 
    { 
     public UpdateContentView(IntPtr handle) : base(handle) 
     { 
     } 



     public override void ViewDidLoad() 
     { 
      base.ViewDidLoad(); 



      var bindingSet = this.CreateBindingSet<UpdateContentView, UpdateContentViewModel>(); 
      bindingSet.Bind(NoConnectionView).For(x => x.Hidden).To(vm => vm.HasConnection).WithConversion("ReverseBoolean"); 
      bindingSet.Bind(UpdateInProgressView).For(x => x.Hidden).To(vm => vm.InProgress).WithConversion("ReverseBoolean"); 
      bindingSet.Bind(UpdateAvailableView).For(x => x.Hidden).To(vm => vm.HasContentUpdate).WithConversion("ReverseBoolean"); 
      bindingSet.Bind(CancelButton).For(x => x.Hidden).To(vm => vm.CancelVisible).WithConversion("ReverseBoolean"); 
      bindingSet.Bind(RetryButton).To(vm => vm.DoRetryUpdate); 
      bindingSet.Bind(ConfirmButton).To(vm => vm.DoUpdate); 
      //bindingSet.Bind(iOSNetworkConnectivitiy).For(x => x.HasNetworkConnection).To(vm => vm.NetworkConnectivitiy).TwoWay() 
         //.For(vm => vm.HasNetworkConnection); 

      bindingSet.Bind(iOSNetworkConnectivitiy).To(vm => vm.NetworkConnectivitiy).TwoWay(); 
      bindingSet.Apply(); 

      _iOSnetworkConnectivity = new NetworkConnectivity() 
      { 
       HasNetworkConnection = Reachability.IsNetworkAvailable() 
      }; 
     } 
     private NetworkConnectivity _iOSnetworkConnectivity { get; set; } 
     public NetworkConnectivity iOSNetworkConnectivitiy { 
      get{return _iOSnetworkConnectivity;} 
      set { _iOSnetworkConnectivity = value; 
      } 
     } 
    } 
} 

は、パブリックビューモデルプロパティに戻りました。

ビューモデルは

using System; 
using System.Threading.Tasks; 
using EdwardsTraining.BusinessLayer.Interfaces.Services; 
using MvvmCross.Core.ViewModels; 
using MvvmCross.Platform; 


namespace Training.Core 
{ 
    public class UpdateContentViewModel : BaseViewModel 
    { 

     private IApplicationContentService _applicationContentService; 
     private ITrainingContentService _trainingContentService; 

     public bool _isNetworkAvailable { get; set; } 


     public UpdateContentViewModel(IApplicationContentService applicationContentService, ITrainingContentService trainingContentService) 
     { 
      _applicationContentService = applicationContentService ?? Mvx.Resolve<IApplicationContentService>(); 
      _trainingContentService = trainingContentService ?? Mvx.Resolve<ITrainingContentService>(); 
      IntialSetup(); 
     } 
     protected void IntialSetup() 
     { 
      _cancelVisible = false; 
      _hasContentUpdate = true; 
      _inProgress = false; 

     } 

     public void SetNoConnection() 
     { 
      _cancelVisible = true; 
      _hasContentUpdate = false; 
      _inProgress = false; 
     } 

     public void SetInProgress() 
     { 
      _cancelVisible = false; 
      HasContentUpdate = false; 
      InProgress = true; 
     } 

     public void SetProgessComplete() 
     { 
      InProgress = false; 
      Task.Run(async() => await FinishedUpdating()); 
     } 

     public async Task UpdateContent() 
     { 
      if (_networkConnectivity.HasNetworkConnection) 
      { 
       SetInProgress(); 

       await _trainingContentService.UpdateTrainingContentAsync(); 
       await _applicationContentService.UpdateContent(); 

       SetProgessComplete(); 
       await FinishedUpdating(); 
      } 
      return; 
     } 

     public async Task FinishedUpdating() 
     { 
      Close(this); 
     } 

     public MvxCommand DoUpdate 
     { 
      get { return new MvxCommand(async() => await UpdateContent()); } 
     } 

     public MvxCommand DoRetryUpdate 
     { 
      get { return new MvxCommand(async() => await UpdateContent()); } 
     } 

     public MvxCommand CancelUpdate 
     { 
      get { return new MvxCommand(async() => await FinishedUpdating()); } 
     } 


     private bool _hasContentUpdate; 

     public bool HasContentUpdate 
     { 
      get { return _hasContentUpdate; } 
      set 
      { 
       _hasContentUpdate = value; 
       RaisePropertyChanged(() => HasContentUpdate); 
      } 
     } 

     private bool _hasConnection; 

     public bool HasConnection 
     { 
      get { return _hasConnection; } 
      set 
      { 
       _hasConnection = value; 
       RaisePropertyChanged(() => HasConnection); 
      } 
     } 

     private bool _inProgress; 

     public bool InProgress 
     { 
      get { return _inProgress; } 
      set 
      { 
       _inProgress = value; 
       RaisePropertyChanged(() => InProgress); 
      } 
     } 

     private bool _cancelVisible; 

     public bool CancelVisible 
     { 
      get { return _cancelVisible; } 
      set 
      { 
       _cancelVisible = value; 
       RaisePropertyChanged(() => CancelVisible); 
      } 
     } 

     private NetworkConnectivity _networkConnectivity { get; set; } 
     public NetworkConnectivity NetworkConnectivitiy 
     { 
      get { return _networkConnectivity; } 
      set { 
       _networkConnectivity = value; 
       RaisePropertyChanged(() => NetworkConnectivitiy); 
      } 
     } 
    } 

    public class NetworkConnectivity 
    { 
     public bool HasNetworkConnection { get; set; } 
    } 
} 

私はこのコード行に問題がある:(_networkConnectivity.HasNetworkConnectionは)私は2つの方法は、結合していても、すでにnullである

public async Task UpdateContent() 
     { 
      if (_networkConnectivity.HasNetworkConnection) 
      { 
       SetInProgress(); 

       await _trainingContentService.UpdateTrainingContentAsync(); 
       await _applicationContentService.UpdateContent(); 

       SetProgessComplete(); 
       await FinishedUpdating(); 
      } 
      return; 
     } 

場合。私は私のアプローチが正しいかどうかわからないこの理由のためにMVVMの十字架に新しいです。

助けてもらえる人はいますか?しかし、結合は、あなたのNetworkConnectivityクラスがどれかを得ていることが通知取得する方法を持っていない

​​

:あなたが明示的にあなたのようなあなたのNetworkConnectivityにバインドしたいプロパティバインディングを伝える必要があり ニック

+0

'_networkConnectivity.HasNetworkConnection'がnullでないのはなぜですか?または、デフォルト値を設定します。つまり、ネットワーク状態はありませんか? – ViVi

答えて

0

その値の更新したがって、あなたは通知を受けることができる何らかの種類のイベントを持つようにそのクラスを拡張しなければならないでしょう。

次に、ターゲットバインディングクラスを作成して登録する必要があります。

あなたは、単にあなたのNetworkConnectivityクラスにINotifyPropertyChangedのを実装するとしましょう:

public class NetworkConnectivity : MvxNotifyPropertyChanged 
{ 
    private bool _hasNetworkConnection; 
    public bool HasNetworkConnection { 
     get { return _hasNetworkConnection; } 
     set { 
      _hasNetworkConnection = value; 
      RaisePropertyChanged(); 
     } 
    } 
} 

次に、あなたがあなたのiOSのプロジェクトでは以下のクラスを作成します。

public class NetworkConnectivityTargetBinding 
    : MvxPropertyInfoTargetBinding<NetworkConnectivity> 
{ 
    public NetworkConnectivityTargetBinding(object target, PropertyInfo targetPropertyInfo) 
     : base(target, targetPropertyInfo) 
    { 
     var view = View; 
     if (view == null) 
     { 
      MvxBindingTrace.Trace(MvxTraceLevel.Error, 
       "NetworkConnectivity is null in NetworkConnectivityTargetBinding"); 
     } 
     else 
     { 
      view.PropertyChanged += HandleValueChanged; 
     } 
    } 

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

    public override MvxBindingMode DefaultMode => MvxBindingMode.TwoWay; 

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

その後Setup.csオーバーライドFillTargetFactoriesに:

protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry) 
{ 
    registry.RegisterPropertyInfoBindingFactory(typeof(NetworkConnectivityTargetBinding), 
               typeof(NetworkConnectivity), "HasNetworkConnection"); 

    base.FillTargetFactories(registry); 
} 

これでTwoWayバインディングが機能するようになりました。また、バインディング式から.For(v => v.HasNetworkConnection)を削除する必要があります。

関連する問題