1

で使用すると、ViewModelからViewに変更が反映されるのに少し行き詰まりますMvxBindableTableViewCell。iOSでMvvmCrossのvNextブランチを使用しています。

すべてが適切に設定されており、リストを初めてロード/表示するときに初期値が表示されます。リストはでObservableCollection<T>あり、ViewModelsはから継承しMvxViewModelます(したがって、INotifyPropertyChangedを実装します)。

メインのViewModelは次のようになります。

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);
        }
    }


アイテムViewModelは次のようになります。

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はUploadItemViewModel、BindingTextを介してにバインドされます。

public const string BindingText = @"ProgressMarker Progress, Converter=Float;";

Uploaderスニペットで言及されているクラスはUploadListViewModel、IProgressReporterで進行状況を設定しようとするプライベートメソッドを実装します。

    float progressValue;
    void SetProgress (float newvalue)
    {
        progressValue = newvalue;

        this.dispatcher.InvokeOnMainThread (delegate {
            if (ProgressReporter != null)
                ProgressReporter.Progress = progressValue;
        });
    }

リストを最初に表示すると、ViewModelとViewの両方のプロパティがヒットしていることがわかりますが、インターフェイスIProgressReporterを介してViewModelを更新すると、tableviewcellのViewの新しい値がProgress更新されず、プロパティが呼び出されません。 。

私は何を間違っているのですか、それともここで何が欠けていますか?

更新:この質問への回答を確認してください。

4

1 に答える 1

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;
    }
于 2013-03-28T00:58:16.237 に答える