2014-03-04 4 views
3

소스 속성이 변경 될 때마다 내 테이블보기가 업데이트되지 않습니다. 다음과 같이 코드는 다음과 같습니다변경된 속성에서 MvvmCross iOS UITableView가 업데이트되지 않습니다.

의 ViewController :

public override void ViewDidLoad() 
    { 
     base.ViewDidLoad(); 
     View.BackgroundColor = UIColor.White; 

     var table = new UITableView(new RectangleF(0, 80, Device.Width, Device.Height - 80)); 
     Add(table); 
     var source = new MvxStandardTableViewSource(table, "TitleText SessionInfo"); 
     table.Source = source; 

     var set = this.CreateBindingSet<JoinSessionViewController, JoinSessionViewModel>(); 
     set.Bind(source).To(vm => vm.AvailableServers); 
     set.Apply(); 

     table.ReloadData(); 
    } 

뷰 모델 :

private readonly INetworkSessionClient _client; 

    public JoinSessionViewModel(INetworkSessionClient client) 
    { 
     _client = client; 

     _client.ServerFound += ClientOnServerFound; 
     _client.BeginSearchingForServers(); 
    } 

    private void ClientOnServerFound(object sender, ServerFoundEventArgs serverFoundEventArgs) 
    { 
     if (AvailableServers.Any(s => s.Identifier == serverFoundEventArgs.ServerInfo.Identifier)) 
      return; 

     AvailableServers.Add(serverFoundEventArgs.ServerInfo); 
     RaisePropertyChanged(() => AvailableServers); 
    } 

    private List<ServerInfo> _availableServers; 
    public List<ServerInfo> AvailableServers 
    { 
     get { return _availableServers; } 
     set { _availableServers = value; RaisePropertyChanged(() => AvailableServers); } 
    } 

답변

4

이 까다로운 일이었다. 난 단지 새로운 목록에 설정 목록에 추가하지 않았기 때문에

https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding.Touch/Views/MvxTableViewSource.cs#L56

public virtual IEnumerable ItemsSource 
    { 
     get { return _itemsSource; } 
     set 
     { 
      if (_itemsSource == value) // **** This one **** 
       return; 

      if (_subscription != null) 
      { 
       _subscription.Dispose(); 
       _subscription = null; 
      } 

      _itemsSource = value; 

      var collectionChanged = _itemsSource as INotifyCollectionChanged; 
      if (collectionChanged != null) 
      { 
       _subscription = collectionChanged.WeakSubscribe(CollectionChangedOnCollectionChanged); 
      } 

      ReloadTableData(); 
     } 
    } 

, 세터()가 반환 초기이고 ReloadTableData을 발사하지 : 범인은 MvxTableViewSource에서이 라인입니다. 수정 사항은 List 대신 ObservableCollection (또는 INotifyCollectionChanged를 구현하는 다른 것)을 사용하는 것이 었습니다.

private void ClientOnServerFound(object sender, ServerFoundEventArgs serverFoundEventArgs) 
    { 
     if (AvailableServers.Any(s => s.Identifier == serverFoundEventArgs.ServerInfo.Identifier)) 
      return; 

     // CollectionChanged event is not automatically martialed to UI thread 
     InvokeOnMainThread(() => AvailableServers.Add(serverFoundEventArgs.ServerInfo)); 
    } 

    private ObservableCollection<ServerInfo> _availableServers; 
    public ObservableCollection<ServerInfo> AvailableServers 
    { 
     get { return _availableServers; } 
     set { _availableServers = value; RaisePropertyChanged(() => AvailableServers); } 
    } 

내 특별한 경우 때문에 ServerFound 이벤트가 별도의 스레드에서 호출됩니다. 즉, INotifyCollectionChanged.CollectionChanged 이벤트가 별도의 스레드에서 호출되기 때문에 목록에 서버를 추가하는 작업이 UI가 올바르게 업데이트되도록 InvokeOnMainThread()를 사용하여 주 스레드에 추가해야합니다.

RaisePropertyChanged() 작동 방식과 마찬가지로 CollectionChanged 이벤트가 UI 스레드에서 자동으로 처리되는 것이 좋을 것입니다.

+0

http://stackoverflow.com/questions/18170151/items-not-showing-in-mvxlistview/18181316#18181316을 참조하십시오 -'=='코드 줄의 이유는 최적화입니다 (여러 목록을 방지하기 위해 그림). 누군가가이를 어떻게 든 더 잘 할 수 있다고 생각하거나 (예를 들어 선택적으로 설정하거나 추적을 추가하는 등) 문제에 대해 기록하거나 풀 요청을 보내주십시오. – Stuart

+0

Observable Collection이 RecyclerView에서 Exception으로 실행됩니다. "예외 동안 RealNotifyDataSetChanged 어댑터가 마스크되었습니다. ArgumentException : 'jobject'가 IntPtr.Zero가 아니어야합니다." 목록으로 다시 변경하는 간단한 해결책이 아니며 항목을 삭제하거나 추가하는 경우 .ToList()를 호출하십시오. – Marian

관련 문제