我已经为奇怪的 DataBinding 问题苦苦挣扎了一段时间,这种问题似乎只发生在 WinRT 中。My Phone Project 使用相同的代码并且可以正常工作。
下面代码的第一个版本不适用于 WinRT,而第二个版本可以。令人困惑的是,我假设对“Icon”getter 的调用将始终来自 UI 线程,因此用于异步“DownloadIcon”方法的同步上下文将是正确的。但显然不是。
更令人困惑的是,当访问 getter 和 setter 引发 PropertyChanged 事件时,我已经验证我在同一个线程(线程 3)上 -无论代码版本如何。但只有第二个版本具有下载完成后重新查询图标属性的不良效果。
捆绑:
<DataTemplate x:Key="AppBarAlbumItemTemplateGrid">
<Grid HorizontalAlignment="Left" Width="80" Height="80">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
</Grid.RowDefinitions>
<Border Grid.RowSpan="2" Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding Icon}" Stretch="UniformToFill" />
</Border>
<Grid Grid.Row="1" VerticalAlignment="Bottom" Background="{StaticResource GIFPlayerOverlayBrush}">
<TextBlock Text="{Binding Title}" VerticalAlignment="Center" FontSize="10" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Margin="5,0"/>
</Grid>
</Grid>
</DataTemplate>
这不能正常工作:
public class Album : AlbumBase
{
WeakReference<ImageSource> icon;
public ImageSource Icon
{
get
{
ImageSource result;
if (icon != null && icon.TryGetTarget(out result))
return result;
DownloadIcon();
return null;
}
private set
{
this.RaiseAndSetIfChanged(ref icon, new WeakReference<ImageSource>(value));
}
}
async void DownloadIcon()
{
Icon = await imageHelper.LoadImageFromUrlAsync(IconUrl, AppSettings.ThumbnailsFolder);
}
}
这个可以,但为什么甚至需要捕获上下文?
public class Album : AlbumBase
{
public Album()
{
this.synchronizationContext = SynchronizationContext.Current;
}
private SynchronizationContext synchronizationContext;
WeakReference<ImageSource> icon;
public ImageSource Icon
{
get
{
ImageSource result;
if (icon != null && icon.TryGetTarget(out result))
return result;
DownloadIcon();
return null;
}
private set
{
this.synchronizationContext.Post((x) =>
{
this.RaiseAndSetIfChanged(ref icon, new WeakReference<ImageSource>(value));
}, null);
}
}
async void DownloadIcon()
{
Icon = await imageHelper.LoadImageFromUrlAsync(IconUrl, AppSettings.ThumbnailsFolder);
}
}