I have set of images and I am replacing the image source in a button click event. I am getting the flickering effect when replacing the image source. How to resolve this ?
Sample
<StackPanel>
<StackPanel Orientation="Horizontal">
<Image x:Name="image1" Height="200" Width="200" Source="ms-appx:///Assets/custom200.png"/>
<Image x:Name="image2" Height="200" Width="200" Source="ms-appx:///Assets/custom201.png"/>
<Image x:Name="image3" Height="200" Width="200" Source="ms-appx:///Assets/custom202.png"/>
<Image x:Name="image4" Height="200" Width="200" Source="ms-appx:///Assets/custom203.png"/>
</StackPanel>
<Button Height="50" Width="150" HorizontalAlignment="Center" VerticalAlignment="Center"
Content="Replace OSM" x:Name="replaceOSM" Click="replace_Click" Margin="5"/>
</StackPanel>
private void replace_Click(object sender, RoutedEventArgs e)
{
image1.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM200.png",
UriKind.RelativeOrAbsolute));
image2.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM201.png",
UriKind.RelativeOrAbsolute));
image3.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM202.png",
UriKind.RelativeOrAbsolute));
image4.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM203.png",
UriKind.RelativeOrAbsolute));
}
For the flickering effect is changed fast. And it does the code that cost too long in UI thread.
You can use bitmapImage.SetSourceAsync
to wait for the image load.
private async Task SetSourceAsync(Image image, Uri uri)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
var file = await StorageFile.GetFileFromApplicationUriAsync(uri);
var bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(await file.OpenAsync(FileAccessMode.Read));
image.Source = bitmapImage;
});
}
You can change your code
image1.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM200.png",
UriKind.RelativeOrAbsolute));
image2.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM201.png",
UriKind.RelativeOrAbsolute));
image3.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM202.png",
UriKind.RelativeOrAbsolute));
image4.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM203.png",
UriKind.RelativeOrAbsolute));
image5.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM210.png",
UriKind.RelativeOrAbsolute));
image6.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM211.png",
UriKind.RelativeOrAbsolute));
image7.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM212.png",
UriKind.RelativeOrAbsolute));
image8.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM213.png",
UriKind.RelativeOrAbsolute));
image9.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM220.png",
UriKind.RelativeOrAbsolute));
image10.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM221.png",
UriKind.RelativeOrAbsolute));
image11.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM222.png",
UriKind.RelativeOrAbsolute));
image12.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM223.png",
UriKind.RelativeOrAbsolute));
To
private async void Replace_Click(object sender, RoutedEventArgs e)
{
await SetSourceAsync(image1, new Uri("ms-appx:///Assets/OSM200.png",
UriKind.RelativeOrAbsolute));
await SetSourceAsync(image2, new Uri("ms-appx:///Assets/OSM201.png",
UriKind.RelativeOrAbsolute));
await SetSourceAsync(image3, new Uri("ms-appx:///Assets/OSM202.png",
UriKind.RelativeOrAbsolute));
await SetSourceAsync(image4, new Uri("ms-appx:///Assets/OSM203.png",
UriKind.RelativeOrAbsolute));
await SetSourceAsync(image5, new Uri("ms-appx:///Assets/OSM210.png",
UriKind.RelativeOrAbsolute));
await SetSourceAsync(image6, new Uri("ms-appx:///Assets/OSM211.png",
UriKind.RelativeOrAbsolute));
await SetSourceAsync(image7, new Uri("ms-appx:///Assets/OSM212.png",
UriKind.RelativeOrAbsolute));
await SetSourceAsync(image8, new Uri("ms-appx:///Assets/OSM213.png",
UriKind.RelativeOrAbsolute));
await SetSourceAsync(image9, new Uri("ms-appx:///Assets/OSM220.png",
UriKind.RelativeOrAbsolute));
await SetSourceAsync(image10, new Uri("ms-appx:///Assets/OSM221.png",
UriKind.RelativeOrAbsolute));
await SetSourceAsync(image11, new Uri("ms-appx:///Assets/OSM222.png",
UriKind.RelativeOrAbsolute));
await SetSourceAsync(image12, new Uri("ms-appx:///Assets/OSM223.png",
UriKind.RelativeOrAbsolute));
}
But it always is flickering when the code run in some poor GPU.
I think the other way is Hide and Show the Image or making an animation.
The hide and show way is make some panel that will show one of the panel.
<StackPanel x:Name="custom">
<StackPanel Orientation="Horizontal">
<Image x:Name="image1" Height="200" Width="200" Source="ms-appx:///Assets/custom200.png"/>
<Image x:Name="image2" Height="200" Width="200" Source="ms-appx:///Assets/custom201.png"/>
<Image x:Name="image3" Height="200" Width="200" Source="ms-appx:///Assets/custom202.png"/>
<Image x:Name="image4" Height="200" Width="200" Source="ms-appx:///Assets/custom203.png"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Image x:Name="image5" Height="200" Width="200" Source="ms-appx:///Assets/custom210.png"/>
<Image x:Name="image6" Height="200" Width="200" Source="ms-appx:///Assets/custom211.png"/>
<Image x:Name="image7" Height="200" Width="200" Source="ms-appx:///Assets/custom212.png"/>
<Image x:Name="image8" Height="200" Width="200" Source="ms-appx:///Assets/custom213.png"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Image x:Name="image9" Height="200" Width="200" Source="ms-appx:///Assets/custom220.png"/>
<Image x:Name="image10" Height="200" Width="200" Source="ms-appx:///Assets/custom221.png"/>
<Image x:Name="image11" Height="200" Width="200" Source="ms-appx:///Assets/custom222.png"/>
<Image x:Name="image12" Height="200" Width="200" Source="ms-appx:///Assets/custom223.png"/>
</StackPanel>
</StackPanel>
<StackPanel x:Name="Osm" Visibility="Collapsed">
<StackPanel Orientation="Horizontal">
<Image Height="200" Width="200" Source="ms-appx:///Assets/OSM200.png"/>
<Image Height="200" Width="200" Source="ms-appx:///Assets/OSM201.png"/>
<Image Height="200" Width="200" Source="ms-appx:///Assets/OSM202.png"/>
<Image Height="200" Width="200" Source="ms-appx:///Assets/OSM203.png"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Image Height="200" Width="200" Source="ms-appx:///Assets/OSM210.png"/>
<Image Height="200" Width="200" Source="ms-appx:///Assets/OSM211.png"/>
<Image Height="200" Width="200" Source="ms-appx:///Assets/OSM212.png"/>
<Image Height="200" Width="200" Source="ms-appx:///Assets/OSM213.png"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Image Height="200" Width="200" Source="ms-appx:///Assets/OSM220.png"/>
<Image Height="200" Width="200" Source="ms-appx:///Assets/OSM221.png"/>
<Image Height="200" Width="200" Source="ms-appx:///Assets/OSM222.png"/>
<Image Height="200" Width="200" Source="ms-appx:///Assets/OSM223.png"/>
</StackPanel>
</StackPanel>
And you can write some button and click
<StackPanel Orientation="Horizontal">
<Button Height="50" Width="150" HorizontalAlignment="Center" VerticalAlignment="Center"
Content="ReplaceCustom" Click="ShowCustom_OnClick" Margin="5"/>
<Button Height="50" Width="150" HorizontalAlignment="Center" VerticalAlignment="Center"
Content="Replace OSM" Click="ShowReplace_OnClick" Margin="5"/>
</StackPanel>
You can show the panel when the button is clicked.
private void ShowCustom_OnClick(object sender, RoutedEventArgs e)
{
custom.Visibility = Visibility.Visible;
Osm.Visibility = Visibility.Collapsed;
}
private void ShowReplace_OnClick(object sender, RoutedEventArgs e)
{
custom.Visibility = Visibility.Collapsed;
Osm.Visibility = Visibility.Visible;
}