2013-03-25 53 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

相關問題