當在MvxBindableTableViewCell
中使用時,有點困擾從ViewModel反射到視圖。我在iOS上使用MvvmCross的vNext分支。如何將視圖模型中的更改反映到具有MVVM交叉綁定的tableviewcell視圖中
所有設置都正確,首次加載/顯示列表時初始值可見。該列表是ObservableCollection<T>
,ViewModel繼承自MvxViewModel
(因此實現了INotifyPropertyChanged)。
主視圖模型看起來是這樣的:
public abstract class BaseViewModel : MvxViewModel, IMvxServiceConsumer
{
//... just regular implementation
}
public class UploadListViewModel: BaseViewModel
{
private readonly IUploadItemTasks uploadItemTasks;
private readonly IPhotoPickerService photoPickerService;
public IObservableCollection<UploadItemViewModel> Uploads { get { return this.LoadUploadItems(); } }
public UploadListViewModel()
{
this.uploadItemTasks = this.GetService<IUploadItemTasks>();
this.photoPickerService = this.GetService<IPhotoPickerService>();
}
private IObservableCollection<UploadItemViewModel> LoadUploadItems()
{
using (var unitOfWork = UnitOfWork.Start())
{
return new SimpleObservableCollection<UploadItemViewModel>(uploadItemTasks.GetAll());
}
}
public void StartUpload()
{
if (this.Uploads == null || this.Uploads.Count == 0) {
ReportError("Error", "No images to upload");
return;
}
this.Uploads.ForEach (uploadItem => PostCallback (uploadItem));
}
private void PostCallback (UploadItemViewModel uploadAsset)
{
IProgressReporter progressReporter = uploadAsset;
this.photoPickerService.GetAssetFullImage(uploadAsset.ImageUrl,
(image) => {
UIImage fullImage = image;
NSData jpeg = fullImage.AsJPEG();
byte[] jpegBytes = new byte[jpeg.Length];
System.Runtime.InteropServices.Marshal.Copy(jpeg.Bytes, jpegBytes, 0, Convert.ToInt32(jpeg.Length));
MemoryStream stream = new MemoryStream(jpegBytes);
Uri destinationUrl = new Uri(uploadAsset.DestinationUrl + "&name=" + uploadAsset.Name + "&contentType=image%2FJPEG");
//TO DO: Move this to plugin
var uploader = new Uploader().UploadPicture (destinationUrl, stream, UploadComplete, progressReporter);
uploader.Host = uploadAsset.Host;
ThreadPool.QueueUserWorkItem (delegate {
uploader.Upload();
jpeg = null;
});
});
}
private void UploadComplete (string name)
{
if (name == null){
ReportError("Error","There was an error uploading the media.");
} else
{
//ReportError("Succes", name);
}
}
該項目視圖模型看起來像:
public interface IProgressReporter
{
float Progress { get; set;}
}
public abstract class BaseAssetViewModel: BaseViewModel, IBaseAssetViewModel
{
//... just regular properties
}
public class UploadItemViewModel: BaseAssetViewModel, IProgressReporter
{
public UploadItemViewModel(): base()
{
}
private float progress;
public float Progress {
get {
return this.progress;
}
set {
this.progress = value;
this.RaisePropertyChanged(() => Progress);
}
}
}
爲項目的視圖從MvxBindableTableViewCell
繼承和擁有的財產:
private float progress;
public float ProgressMarker {
get {
return progress;
}
set {
progress = value;
// change progressbar or textfield here
}
}
的tableviewcell爲界經由BindingText的UploadItemViewModel
:在UploadListViewModel
片斷提到
public const string BindingText = @"ProgressMarker Progress, Converter=Float;";
的Uploader
類實現試圖設置在IProgressReporter進展的私有方法。
float progressValue;
void SetProgress (float newvalue)
{
progressValue = newvalue;
this.dispatcher.InvokeOnMainThread (delegate {
if (ProgressReporter != null)
ProgressReporter.Progress = progressValue;
});
}
在列表中,我可以看到,在這兩個視圖模型和視圖屬性正在被擊中的第一次觀看,但是當我通過接口IProgressReporter
用新值Progress
更新視圖模型在tableviewcell查看沒有更新,也沒有被調用。
我在做什麼錯,或者我在這裏錯過了什麼?
更新:檢查這個問題的答案。
有沒有更多的代碼可以發佈?也許是一個要點,包括項目在你的列表中的類別和包含該列表的ViewModel的位。另外,我在這裏通過'Mode = TwoWay'這個位置感到困惑 - 只是檢查我沒有誤解你所問的內容。 – Stuart 2013-03-25 20:46:02
我用更多的代碼更新了我的問題。希望現在更清楚。我刪除了'Mode = TwoWay'部分,因爲這是一些測試的剩餘部分。它應該是'單向';從ViewModel到View。 – 2013-03-26 11:27:22
謝謝 - 我看不到任何錯誤。我打算試着明天得到一個repro(但時間對我來說) – Stuart 2013-03-26 21:42:09