如何更新绑定到后台工作程序的选项卡控件的图像集合?

时间:2011-04-05 15:21:45

标签: wpf backgroundworker tabcontrol bitmapimage

这是我第一篇关于stackoverflow的帖子,所以如果我做错了什么我道歉。我有一个利用Prism和MVVM模式的WPF应用程序。在我的视图中,我有一个TabControl,它有一个自定义数据模板,并绑定到一个名为ShippingLabel的类的ObservableCollection。

用于TabControl的Xaml:

<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>

我创建的Helper类绑定到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();
}

但是,当我尝试此操作时,UI将仅显示带有名称的选项卡,但选项卡内容中没有图像。我试图让我的班级支持INotifyPropertyChanged认为它是那里的东西,但没有任何区别。所以问题是需要做什么才能正确通知UI集合的Image属性已更改以便更新?

1 个答案:

答案 0 :(得分:1)

由于您注意到标签的名称已显示,因此这可能是图像本身特有的。绑定看起来很好。

如果你的图像是在背景工作者上创建的,你必须非常小心,BitmapImage具有线程亲和力,并且load one in the background比较复杂,需要将其冻结才能传回。 / p>

你确定某个背景工作者在某处没有例外吗?