2011-04-05 1 views
0

これは私が間違って何かをした場合、私は謝罪するstackoverflowに私の最初の投稿です。私はPrismとMVVMパターンを利用するWPFアプリケーションを持っています。私の見解では、カスタムデータテンプレートを持ち、ShippingLabelというクラスのObservableCollectionにバインドされたTabControlがあります。バックグラウンドワーカーからタブコントロールにバインドされたイメージのコレクションを更新するにはどうすればよいですか?

TabControlのためのXAML:私は当初、私は私のViewModelのコンストラクタで行うために必要なすべての作業をしていた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; } 
} 

にバインドするために作成さ

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

ヘルパークラス、 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にしようとしました。ですから、コレクションのImageプロパティが更新されるようにUIが正しく通知されるためには、何が必要なのでしょうか?

答えて

1

ラベルの名前が表示されているので、これはおそらく画像そのものに固有のものです。バインディングはきれいに見えます。

BitmapImageはスレッドアフィニティを持っており、load one in the backgroundには比較的複雑であるため、バックグラウンドワーカーに画像を作成する場合は、凍結して戻す必要があります。

バックグラウンドワーカーがどこかで飲み込んでいる例外はありませんか?

+0

RunWorkerCompletedメソッドにブレークポイントを設定すると、新しいShippingLabelクラスがコレクションに追加されているように見えるので、そうは思わないでしょう。 – Jeremie

関連する問題