標籤:
Binding之於MVVM來說的重要性無需多說,Binding之於DataTemplate來說的重要性也無需多說,Binding的重要性也無需多說,非同步也不用多說了,今天就到此為止吧。。。
-------------------------------------------------冷冷的分割線------------------------------------------------------
但是,當你要binding的資料是一個需要非同步作業的結果的時候呢?
這是我們在項目中遇到的實際問題,一度困擾了我很長時間,這篇文章是我探索的過程,在這個過程中,我嘗試用不同的方案來解決這個問題,並且諮詢了其它朋友,終於找到了一種解決方案,而且更加深入地瞭解了DataTemplate的工作機制,我覺得很有必要紀錄下來,重新梳理這個探索的過程,應該會對遇到同樣問題的同學有所協助。
我們的需求:
顯示一組縮圖的濾鏡效果,使用者點擊了這個濾鏡,可以在頁面上看到應用了這個濾鏡的效果 ,類似於這種效果
我們的解決方案:
1. 需要一個項集合控制項,類似於ListBox (UI工作)
2. 需要一個ItemControl,用於顯示濾鏡的名稱和處理過的縮圖(UI)
3. 需要一個濾鏡類,需要包含濾鏡名和濾鏡資訊(資料)
4. UI與資料結合
開始動手--方案一:
1. 先把資料做起來,我們給出了這麼一個類,代表我的濾鏡
public class MyFilter{ public FilterData Filter{get;set;} // 濾鏡相關資訊 public FilterName Name{get;set;} // 濾鏡名}
2. 項集合控制項,MyItemsControl,有一個ItemsSource,接收一個List<MyFilter>的資料來源
3. Item控制項,用於顯示濾鏡名和展示應用過該濾鏡的縮圖,MyItemControl,我只需要一個資料來源,將MyItemControl的DataContext設定為這個資料來源,然後使用binding就OK,由於Image需要的是一個ImageSource的資料來源,所以我還需要一個轉換器,將FilterData轉換為WriteableBitmap
<UserControl.Resources>
<local:WriteableBitmapConverter x:name="imageConverter"/>
</UserControl.Resources>
<UserControl> <Grid> <Image x:Name="FilterImage" Binding={MyFilterData, Converter={StaticResource imageConverter} /> <TextBlock x:Name="FilterNameTB" Binding= {MyFilterName}/> </Grid></UserControl>
4. 最後一步,實現這個WriteableBitmapConverter,將資料轉換為可以被Image接收的WriteableBitmap:
public class ImageConverter : IValueConverter { public async Task<object> Convert(object value, Type targetType, object parameter, string language) { WriteableBitmap thumb = await SDK.GetThumbAsync(); var filterData = value as MyFilterData; WriteableBitmap renderedResult = await SDK.RenderAsync(thumb, filterData); return renderedResult; } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } }
OH,NO!為了保證使用者體驗和UI的流暢性,我的SDK被設計成了非同步作業,轉換器裡面能這麼寫嗎?答案很明顯,不行。
那麼問題來了:當Binding遇到非同步時候,該怎麼辦?
Windows 10 開發日記(四)-- 當Binding遇到非同步 -- 問題的引出