转载

Windows 10 开发日记(四)-- 当Binding遇到异步 -- 问题的引出

Binding之于MVVM来说的重要性无需多说,Binding之于DataTemplate来说的重要性也无需多说,Binding的重要性也无需多说,异步也不用多说了,今天就到此为止吧。。。

-------------------------------------------------冷冷的分割线------------------------------------------------------

但是,当你要binding的数据是一个需要异步操作的结果的时候呢?

这是我们在项目中遇到的实际问题,一度困扰了我很长时间,这篇文章是我探索的过程,在这个过程中,我尝试用不同的方案来解决这个问题,并且咨询了其它朋友,终于找到了一种解决方案,而且更加深入地了解了DataTemplate的工作机制,我觉得很有必要纪录下来,重新梳理这个探索的过程,应该会对遇到同样问题的同学有所帮助。

我们的需求:

显示一组缩略图的滤镜效果,用户点击了这个滤镜,可以在页面上看到应用了这个滤镜的效果 ,类似于这种效果

Windows 10 开发日记(四)-- 当Binding遇到异步 -- 问题的引出

我们的解决方案:

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遇到异步的时候,该怎么办?

正文到此结束
Loading...