如何实现ImageButton绑定,仅在图片加载完成后才显示?
问题原因
你遇到的切换空白是因为绑定值变更触发INotifyPropertyChanged通知后,StringToSourceConverter才会开始加载嵌入式资源生成可用的ImageSource,这个加载过程的耗时就是空白出现的窗口。同时ImageButton默认会在绑定源变更时立即清除旧图,等新图加载完成后才渲染新内容,两者的时间差就导致了空白断层。
解决方案(按优先级排序)
方案1:预加载所有ImageSource(嵌入式资源场景最优)
直接将Game数组从存储资源路径的string类型改为存储预加载完成的ImageSource类型,页面初始化阶段就把所有要用到的嵌入式资源提前转为ImageSource缓存起来,点击交换时直接交换已经加载完成的对象,不需要临时走转换器加载,完全消除加载耗时。
ViewModel代码示例:
// 原Game为string[],修改为ImageSource[] public ImageSource[] Game { get; set; } // 页面初始化时执行一次预加载 void InitGameResources() { // 替换为你自己的资源路径和程序集信息 Game[0] = ImageSource.FromResource("YourProjectNamespace.Resources.img1.png", typeof(YourViewModel).Assembly); Game[1] = ImageSource.FromResource("YourProjectNamespace.Resources.img2.png", typeof(YourViewModel).Assembly); OnPropertyChanged(nameof(Game)); } // 原有交换逻辑无需修改,交换后直接触发通知即可 void Clicked(object sender, EventArgs e) { (Game[0], Game[1]) = (Game[1], Game[0]); OnPropertyChanged(nameof(Game)); }
XAML中去掉转换器即可:
<ImageButton Grid.Column="15" Grid.Row="20" Clicked="Clicked" Source="{Binding Game[0]}" /> <ImageButton Grid.Column="15" Grid.Row="20" Clicked="Clicked" Source="{Binding Game[1]}" />
方案2:双缓冲重叠显示(需保留字符串绑定时使用)
给每个显示位置放两个重叠的ImageButton,一个负责显示当前图片,另一个默认隐藏用于预加载下一张图片,监听隐藏控件的ImageLoaded事件,确认新图加载完成后再切换两个控件的可见性,保证切换时新图已经完全准备好。
XAML结构示例:
<Grid Grid.Column="15" Grid.Row="20"> <ImageButton x:Name="DisplayBtn" Clicked="Clicked" Source="{Binding Game[0], Converter={StaticResource StringToSourceConverter}}" IsVisible="True"/> <ImageButton x:Name="BufferBtn" Clicked="Clicked" Source="{Binding BufferSource[0], Converter={StaticResource StringToSourceConverter}}" IsVisible="False" ImageLoaded="BufferLoaded"/> </Grid>
后台逻辑先给BufferSource赋值,等BufferLoaded事件触发后再交换Game数组的值、切换两个控件的可见性即可。
方案3:占位符兜底(最小改动兼容原有逻辑)
如果不想调整现有绑定逻辑,可以给ImageButton设置占位符为当前正在显示的图片,同时关闭默认的淡入切换动画,避免放大空白感知:
<ImageButton FadeAnimationEnabled="False" Placeholder="{Binding CurrentDisplayImage}" Source="{Binding Game[0], Converter={StaticResource StringToSourceConverter}}" Clicked="Clicked"/>
新图加载的过程中会一直显示旧的占位图片,不会出现完全空白的情况。
内容的提问来源于stack exchange,提问作者Luca Hafer
相关产品推荐
相关产品推荐

