2013-03-25 56 views
1

当在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查看没有更新,也没有被调用。

我在做什么错,或者我在这里错过了什么?

更新:检查这个问题的答案。

+0

有没有更多的代码可以发布?也许是一个要点,包括项目在你的列表中的类别和包含该列表的ViewModel的位。另外,我在这里通过'Mode = TwoWay'这个位置感到困惑 - 只是检查我没有误解你所问的内容。 – Stuart 2013-03-25 20:46:02

+0

我用更多的代码更新了我的问题。希望现在更清楚。我删除了'Mode = TwoWay'部分,因为这是一些测试的剩余部分。它应该是'单向';从ViewModel到View。 – 2013-03-26 11:27:22

+0

谢谢 - 我看不到任何错误。我打算试着明天得到一个repro(但时间对我来说) – Stuart 2013-03-26 21:42:09

回答

1

我发现为什么绑定不起作用。我一次又一次地替换了ObservableCollection ..我按照下面的说明更改了这段代码,现在它反映了单元格视图中对UploadItemViewModel所做的更改。

private IObservableCollection<UploadItemViewModel> uploads; 
    private IObservableCollection<UploadItemViewModel> LoadUploadItems() 
    { 
     if (uploads == null) 
     { 
      using (var unitOfWork = UnitOfWork.Start()) 
      { 
       uploads = new SimpleObservableCollection<UploadItemViewModel>(uploadItemTasks.FindAll()); 
      } 
     } 
     return uploads; 
    } 
+0

谢谢@Remco的自我回应!我昨天建立了一个v3的案例 - 它的工作......所以我今天会尝试v2 ......但现在我不需要:) – Stuart 2013-03-28 05:54:36

相关问题