2014-03-06 3 views
0

저는 MVVMCross에 매우 익숙합니다. & Xamarin, 그래서 저는 간단한 것을 놓치고있을 가능성이 있습니다. 그러나 Mvx.MvxGridView 레이아웃은 간단한 객체 목록에 바인딩되어 있습니다.MVVMCross (Droid) GridView가 포커스없이 업데이트되지 않습니까?

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:local="http://schemas.android.com/apk/res-auto" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <Mvx.MvxGridView 
     android:numColumns="5" 
     android:verticalSpacing="15dp" 
     android:horizontalSpacing="15dp" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     local:MvxBind="ItemsSource Bikes" 
     local:MvxItemTemplate="@layout/bikeassignmentview_bikeelement" /> 
</LinearLayout> 

전망은 매우 간단하다 :

뷰 모델과 동일
namespace Keiser.MPM.Screen.Droid.Views 
{ 
    using Android.App; 

    [Activity(Theme = "@style/Theme.FullScreen")] 
    public class BikeAssignmentView : BaseView 
    { 
     protected override void OnCreate(Android.OS.Bundle bundle) 
     { 
      base.OnCreate(bundle); 
      this.SetContentView(Resource.Layout.BikeAssignmentView_Page); 
     } 
    } 
} 

:

자전거리스트가 실제로 원래이 서비스는 아래로 모든 방법을 중첩

namespace Keiser.MPM.Screen.Core.ViewModels 
{ 
    using System.Collections.Generic; 
    using System.Windows.Input; 
    using Cirrious.CrossCore; 
    using Cirrious.MvvmCross.ViewModels; 
    using Keiser.MPM.Screen.Core.Models.Bikes; 

    public class BikeAssignmentViewModel : BaseViewModel 
    { 
     private IBikeManagerService _bikeManagerService; 
     private List<Bike> _bikes; 
     public List<Bike> Bikes { get { return _bikes; } } 

     public BikeAssignmentViewModel(IBikeManagerService bikeManagerService) 
     { 
      _bikeManagerService = bikeManagerService; 
      _bikes = _bikeManagerService.Bikes; 
     } 
    } 
} 
서비스 클래스 :

namespace Keiser.MPM.Screen.Core.Models.Bikes 
{ 
    using System; 
    using System.Linq; 
    using System.Threading; 
    using System.Collections.Generic; 
    using Cirrious.CrossCore; 
    using Cirrious.CrossCore.Core; 
    using Cirrious.MvvmCross.ViewModels; 
    using Cirrious.MvvmCross.Plugins.Messenger; 
    using Core.Models.Settings; 

    public class BikeManagerService : MvxNotifyPropertyChanged, IBikeManagerService 
    { 
     public object BikesLocker = new object(); 
     private List<Bike> _bikes = new List<Bike>(); 
     public List<Bike> Bikes 
     { 
      get { return _bikes; } 
      set { _bikes = value; RaisePropertyChanged(() => Bikes); } 
     } 

     // --- Other boring code... 
    } 
} 

여기에 문제가 있습니다. 뷰가로드 될 때 목록이 비어 있으면 그리드 뷰는 동적으로 채워지지 않습니다. 목록이 채워진 페이지를 입력하면 올바르게로드되고 목록에 추가 된 새 개체에 대해 표가 추가되지만 화면을 조금 클릭 할 때까지 목록에서 삭제 된 표가 제거되지는 않습니다. 개체는 삭제 될 때까지 계속해서 올바르게 업데이트됩니다. 그런 다음 대상의 필드가 작동하지 않지만 사라지지 않습니다. 또한 목록이 다시 비어있는 경우보기가 다시 업데이트되지 않습니다.

내가 누락 된 항목이 있습니까? 나는 그 무언가를 무효화해야 하는가? 어떤 도움이나 자원이라도 대단히 감사하겠습니다!

[===================== 해결 방법 ================== ===] 최종 솔루션은 관측 컬렉션에 목록을 변환하는 것이 었습니다

: 인터페이스 :

namespace Keiser.MPM.Screen.Core.Models.Helpers 
{ 
    using System.Collections.Generic; 
    using System.Collections.Specialized; 
    using System.ComponentModel; 

    public interface IObservableCollection<T> 
     : IList<T> 
      , INotifyPropertyChanged 
      , INotifyCollectionChanged 
    { 
    } 
} 

클래스 : 컬렉션에 만든

namespace Keiser.MPM.Screen.Core.Models.Helpers 
{ 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel; 

    public class SimpleObservableCollection<T> 
     : ObservableCollection<T> 
     , IObservableCollection<T> 
    { 
     public SimpleObservableCollection(List<T> source) : base(source) { } 

     protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
     { 
      base.OnCollectionChanged(e); 
     } 
    } 
} 

모든 변경했다가되게합니다 기본 UI 스레드에서 수행됩니다. 성능을 저하시키기 시작했습니다. (나는 지속적인 컨텍스트 스위칭에서 추측하고 있습니다.) 이것은 것을 의미한다 INotifyPropertyChanged

를 사용

namespace Keiser.MPM.Screen.Droid.Views 
{ 
    using Android.App; 
    using Android.Widget; 
    using Cirrious.MvvmCross.Plugins.Messenger; 

    [Activity(Theme = "@style/Theme.FullScreen")] 
    public class BikeAssignmentView : BaseView 
    { 
     protected MvxSubscriptionToken _BikeListToken; 

     protected override void OnCreate(Android.OS.Bundle bundle) 
     { 
      base.OnCreate(bundle); 
      this.SetContentView(Resource.Layout.BikeAssignmentView_Page); 
      var gridView = FindViewById<GridView>(Resource.Id.gridview); 

      _BikeListToken = Cirrious.CrossCore.Mvx.Resolve<IMvxMessenger>().SubscribeOnMainThread<Core.Models.Bikes.BikesChangedMessage>(message => 
      { 
       ((BaseAdapter)gridView.Adapter).NotifyDataSetChanged(); 
      }); 
     } 
    } 
} 

답변

1

정상 MVVM 및 데이터 바인딩 작품 : 나는 관찰 목록을 폐기 및 변경에 메시지를 발사를 IEnumerable 클래스를 구현하고 뷰에서 메시지를 구독 결국 UI의 그리드가 BikeAssignmentViewModelBikes에 그 ItemsSource를 바인딩 할 때 당신이 당신의에서 RaisePropertyChanged을 발사하고 있기 때문에 그것은 BikeAssignmentViewModel

PropertyChanged 이벤트에 후크이고 사용자의 ViewModel이 아니라면 그리드에는이 변경 알림이 표시되지 않습니다.

는이 문제를 해결하려면 다음

  • 당신은
  • 오히려뿐만 아니라 서비스에 그리드를 결합 할 수있는 방법을 찾을 수 오히려 서비스보다 뷰 모델에서 RaisePropertyChange 전화를 올릴 수있는 방법을 찾을 수 ViewModel (예 :당신이 새로운 경우 ItemsSource Service.Books)

바인딩 그것은 또한 독서 가치가있을 수 있습니다 다음 데이터 바인딩의 더 많은 데이터 바인딩의 나열에 대한도 ObservableCollection에 대한 학습 및 INotifyCollectionChanged에 대해 내가 귀하의 게시물 a를 찾는 결국

+0

몇 달 전과 비슷한 상황에서 ObservableCollections를 구현하고 Main UI Thread에서 목록 변경을 수행해야하는 필요성이 있다는 것을 발견했습니다. 이것들이 함께 문제를 해결했습니다. – BayssMekanique

+0

전체 목록을 한 번에 업데이트하는 경우에는 추가 기능이 필요하지 않습니다. 이는 점진적 변경에만 필요합니다. – Stuart

관련 문제