我很新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線程上完成,哪個開始降低性能(我從連續的上下文切換中猜測)?我結束了再殺可觀察的名單和實施一個IEnumerable類火災的變化的消息,訂閱消息中的觀點:使用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();
});
}
}
}
我最終找到您的帖子幾個月後又遇到類似的情況,發現它需要在主UI線程上實現ObservableCollections和執行列表更改。這些共同解決了這個問題。 – BayssMekanique
如果您一次更新整個列表,則不需要obscollection - 僅在增量更改時才需要。 – Stuart