Как обновить коллекцию изображений, привязанных к элементу управления вкладкой из фонового рабочего? - PullRequest
0 голосов
/ 05 апреля 2011

Это мой первый пост в stackoverflow, поэтому, если я сделал что-то не так, прошу прощения. У меня есть приложение WPF, которое использует Prism и шаблон MVVM. На мой взгляд, у меня есть TabControl, который имеет пользовательский шаблон данных и привязан к ObservableCollection класса с именем ShippingLabel.

XAML для TabControl:

<TabControl Grid.Row="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=ShippingLabels}">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <Label Content="{Binding Path=Name}"/>
                </DataTemplate>
            </TabControl.ItemTemplate>
            <TabControl.ContentTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Image Source="{Binding Path=Image}"/>
                    </StackPanel>
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>

Вспомогательный класс, который я создал для привязки к TabControl

public class ShippingLabel
{
/// <summary>
/// Name of the image, this is the text that will be displayed in the Tab
/// </summary>
public string Name { get; set; }
/// <summary>
/// BitmapImage to display for TabContent
/// </summary>
public BitmapImage Image { get; set; }
}

Изначально я выполнял всю работу, которую необходимо было выполнить в Конструкторе моей ViewModel, ViewModel вызывает службу WCF и возвращает ответ, который содержит отгрузочные метки в формате строки в кодировке base64. Это работало нормально, и этикетки отображались правильно в зависимости от количества упаковок, которые они указали для отправки. Чтобы повысить удобство использования, я решил добавить BackgroundWorker для обработки вызова службы и обработки этикеток доставки после завершения работника.

События BackgroundWorker

private void serviceWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  //Present the shipping labels
  ShippingLabels = new ObservableCollection<ShippingLabel>();
  int packageNumber = 0;
  foreach (var result in adapter.CurrentResponse.PackageResults)
  {
    packageNumber++;

    Byte[] labelBytes = new Byte[result.ShippingLabel.Length];
    labelBytes = Convert.FromBase64String(result.ShippingLabel.Replace("\r\n", "").Replace(" ", ""));

    var tempLabel = new BitmapImage();
    tempLabel.BeginInit();
    tempLabel.StreamSource = new MemoryStream(labelBytes);
    tempLabel.Rotation = Rotation.Rotate90;
    tempLabel.EndInit();

    ShippingLabels.Add(new ShippingLabel()
    {
      Name = "Package " + packageNumber.ToString(),
      Image = tempLabel
    });
  }

  ShowBusyIndicator = false;
  RaisePropertyChanged(() => ShippingLabels);
}

private void serviceWorker_DoWork(object sender, DoWorkEventArgs e)
{
  adapter.ProcessShipment();
}

Однако, когда я попытался это сделать, пользовательский интерфейс будет отображать только вкладку с именем, но без изображения в содержимом вкладки. Я пытался заставить свой класс поддерживать INotifyPropertyChanged, думая, что это что-то есть, но это не имело никакого значения. Таким образом, вопрос заключается в том, что нужно сделать для того, чтобы пользовательский интерфейс был правильно уведомлен об изменении свойства Image коллекции для ее обновления?

1 Ответ

1 голос
/ 05 апреля 2011

Поскольку вы заметили, что на этикетке указано название ярлыка, это, вероятно, что-то очень специфичное для самого изображения. Привязки выглядят хорошо.

Если ваши изображения созданы на фоновом рабочем месте, вы должны быть очень осторожны, BitmapImage имеет сходство потоков, и это сравнительно сложно: загрузить одно в фоновом режиме , его нужно заморозить, чтобы переведен обратно.

Вы уверены, что нет никаких исключений, которые где-то проглатывает фоновый работник?

...