Обработчик событий не запускается в Silverlight с использованием MVVM и RIA?

#c# #silverlight #mvvm-light

#c# #серебристый свет #mvvm-light #silverlight

Вопрос:

Так что, должно быть, я делаю здесь что-то не так, просто пока не уверен, что именно. Мой оригинальный PoC работал нормально, но не был MVVM, поэтому я кое-что потерял в переводе.

Итак, я просматриваю файл, который нужно выбрать для загрузки, все начинает работать нормально. Он передает первый фрагмент на сервер, а затем мое полное событие никогда не вызывается. И это приведет к отправке всех дополнительных фрагментов в массиве, поэтому файл будет неполным.

Я просто пропустил шаг?

И если это имеет значение, служба настроена на IIS7, но я не уверен, нужно ли что-то настраивать на стороне службы, чтобы это произошло. Он просто «работал» в коде PoC, когда я использовал код XAML.

Код модели:

 public void uploadChunks(int index, string fileName)
    {
        FileUpload fileUpload = new FileUpload();
        FileUpload.FileName = fileName;
        FileUpload.chunk = fileChunks[index];

        context.UploadFileAsync(fileUpload);
    }

FileUploadServiceSoapClient context = new FileUploadServiceSoapClient("BasicHttpBinding_FileUploadServiceSoap");

    int chunkSize = 15306;
    public List<byte[]> fileChunks;
    public double TotalChunks { get; set; }

    /// <summary>
    /// Convert file to an array of file chunks to stream to the upload location
    /// </summary>
    /// <param name="imageFile"></param>
    public void convertToChunks(byte[] imageFile)
    {
        TotalChunks = Math.Ceiling((double)imageFile.Length / (double)chunkSize);
        fileChunks = new List<byte[]>();

        for (int i = 0; i < TotalChunks; i  )
        {
            byte[] chunk;

            int startIndex = i * chunkSize;
            if (startIndex   chunkSize > imageFile.Length)
                chunk = new byte[imageFile.Length - startIndex];
            else
                chunk = new byte[chunkSize];

            Array.Copy(imageFile, startIndex, chunk, 0, chunk.Length);

            fileChunks.Add(chunk);
        }
    }
  

Код ViewModel

 public UploadViewModel()
    {
        uploadModel = new UploadModel(); // important – must initialize model
        OpenFileCommand = new RelayCommand(OpenDialog);

        StatusText = "Please select a file to upload";

        context.UploadFileCompleted  = new EventHandler<AsyncCompletedEventArgs>(context_UploadFileCompleted);
    }

 private void OpenDialog()
    {
        OpenFileDialog ofd = new OpenFileDialog();
        if ((bool)ofd.ShowDialog())
        {
            _fileName = ofd.File.Name;
            FileStream fs = ofd.File.OpenRead();
            fileSize = (double)fs.Length;
            index = 0;
            sendData = 0;

            byte[] file = new byte[fs.Length];
            fs.Read(file, 0, file.Length);

            // call our model and convert file into chunks
            uploadModel.convertToChunks(file);

            // start upload process, this only sends the first chunk all subsquent chunks
            // are sent on the context_UploadFileToCrmCompleted function
            uploadModel.uploadChunks(index, _fileName);
        }
    }

void context_UploadFileCompleted(object sender, AsyncCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            sendData  = uploadModel.fileChunks[index].Length;
            TotalFileSize = byteTranslation(sendData)   "/"   byteTranslation(fileSize);

            if ((index   1) < uploadModel.fileChunks.Count)
            {
                this.CurrentProgress = index / uploadModel.fileChunks.Count;

                index  = 1;
                uploadModel.uploadChunks(index, _fileName);
            }
            else
            {
                StatusText = "Successfully uploaded. Submitting to the file repository...";

                // Submit the upload to SharePoint
            }
        }
    }
  

Комментарии:

1. И просто обновление. Если я перемещу фрагменты загрузки из модели в viewmodel, все будет запущено правильно. Что должно произойти, чтобы это сработало в модели? Спасибо.

Ответ №1:

Надеюсь, я ничего не упустил… у вас есть два FileUploadServiceSoapClients?

Один в ViewModel и один в модели. Вы вызываете службу в модели, но завершенный обработчик присваивается контексту ViewModel.

Итак, вы должны написать

 uploadModel.context.UploadFileCompleted  = new EventHandler<AsyncCompletedEventArgs>(context_UploadFileCompleted); 
  

вместо

 context.UploadFileCompleted  = new EventHandler<AsyncCompletedEventArgs>(context_UploadFileCompleted);
  

Вероятно, вам лучше не использовать ServiceClient непосредственно в ViewModel, а передать обратный вызов или позволить модели вызвать собственное событие.