我試圖顯示(在具有自定義DataTemplate的ListBox中)從多頁Tiff圖像中提取的一系列BitmapSource框架(縮略圖)。當我在UI線程上處理tiff,並直接將圖像添加到列表框的項目集合或將它們添加到綁定的ObservableCollection時,它們在列表中顯示正常。然而,試圖異步加載每個縮略圖(或者使用的BackgroundWorker或使用異步任務)的時候,我看到的行爲我不能工作了:如預期異步加載時不出現在WPF窗體上的圖像
- 第一縮略圖加載
- 下,和所有後續縮略圖獲得列表中的項目(我看到了邊框),但所有顯示的都是空白圖像。它顯示正確的項目數量,但在第一個之後沒有圖像。
我玩過試圖凍結縮略圖(不行),嘗試將它們發送回UI線程並通過工作人員的ReportProgress將它們添加到集合中(但不行),但我可以似乎沒有讓他們表現出來。
工作UI線程(其中SyncImages是綁定到我的列表框一個ObservableCollection和OnPropertyChanged處理通知事件):
private void LoadSynchronous()
{
Stream imageStreamSource = new FileStream(ImagePath, FileMode.Open, FileAccess.Read, FileShare.Read);
var decoder = BitmapDecoder.Create(imageStreamSource, BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
foreach (var frame in decoder.Frames)
{
//frame.Freeze(); //Tried this but no effect.
SyncImages.Add(frame);
}
OnPropertyChanged("SyncImages");
}
不工作(這個例子中直接添加幀到列表中,但我我也嘗試通過綁定結果沒有任何區別):
private void LoadAsync(object sender, DoWorkEventArgs e)
{
Stream imageStreamSource = new FileStream(ImagePath, FileMode.Open, FileAccess.Read, FileShare.Read);
var decoder = BitmapDecoder.Create(imageStreamSource, BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
foreach (var frame in decoder.Frames)
{
// frame.Freeze();
(sender as BackgroundWorker).ReportProgress(0, frame);
}
OnPropertyChanged("AsyncImages");
}
private void ReportAsyncProgress(object send, ProgressChangedEventArgs e)
{
var frame = (BitmapSource) e.UserState;
LbAsynchronous.Items.Add(frame);
}
希望有人可以對這裏發生的事情有所瞭解。我知道代碼可以提取框架,所以即使在異步示例中它們也必須加載,但看起來好像UI線程無法訪問保存圖像數據以在窗體上顯示它們的源的屬性(這就是爲什麼我試圖凍結)。
任何想法,將不勝感激!
示例圖像:從他原來的問題評論http://i.imgur.com/75wMkmS.png
不知道爲什麼凍結不能正常工作,你可以看一些其他的建議在這裏:http://stackoverflow.com/questions/3034902/怎麼做 - 你從背景線程到線程 - UI-thread-in-wpf – vesan
感謝您的鏈接 - 我一直在檢查這些建議,看看是否有任何結果它。我附上了一張圖片,希望能引發一個推薦:http://i.imgur.com/75wMkmS.png左邊是UI線程處理結果,右邊是BackgroundWorker/async版本。 –
你正在關閉FileStream嗎?爲了確保立即加載所有幀,並且可以在創建BitmapFrame後立即關閉流,應該設置「BitmapCacheOption.OnLoad」而不是「Default」。 – Clemens