我很新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