Nikhil Gupta
Nikhil Gupta

Reputation: 172

Images disappear in Combobox

I have a ComboBox which shows an image and text along with it in a stackpanel. The items are shown when I initially open the ComboBox. When I scroll through the list going down, the images in the items at the top of the list disappear (when I scroll back up to see those items) and vice versa. The text remains intact. Also, even without scrolling, when I select an item from the combobox, that item is displayed without the image in the closed combobox. How to rectify this?

<ComboBox ItemsSource="{Binding ElementName=searchPage, Path=emotionList}"
                               SelectionChanged="ComboBox_SelectionChanged"
                               Name="emotionComboBox"
                               VerticalAlignment="Center">
                            <ComboBox.ItemTemplate>
                                <DataTemplate x:DataType="local:StorageItemThumbnailClass">
                                    <StackPanel Orientation="Horizontal">
                                        <Image Source="{Binding Thumbnail, Converter={StaticResource ImagetoThumbnailConverter}, Mode=OneWay}" Margin="10" MaxHeight="50" MaxWidth="50"/>
                                        <TextBlock Text="{Binding Name}" Style="{StaticResource BodyTextBlockStyle}" Margin="10" TextWrapping="WrapWholeWords" Width="120"/>
                                    </StackPanel>
                                </DataTemplate>
                            </ComboBox.ItemTemplate>
                        </ComboBox>

This method is called from the OnNavigated function of the searchPage in which the combobox is present -

private async Task populateEmotionListAsync()
        {            
            emotionList = new ObservableCollection<StorageItemThumbnailClass>();
            emotionList.Add(new StorageItemThumbnailClass { Name = EmotionEnum.None.ToString(), Thumbnail = null });
            emotionList.Add(new StorageItemThumbnailClass { Name = EmotionEnum.Angry.ToString(), Thumbnail = await (await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/EmotionIcons/angry.png"))).GetThumbnailAsync(ThumbnailMode.PicturesView, 50) });
            emotionList.Add(new StorageItemThumbnailClass { Name = EmotionEnum.Contempt.ToString(), Thumbnail = await (await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/EmotionIcons/contempt.png"))).GetThumbnailAsync(ThumbnailMode.PicturesView, 50) });
            emotionList.Add(new StorageItemThumbnailClass { Name = EmotionEnum.Disgusted.ToString(), Thumbnail = await (await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/EmotionIcons/disgust.png"))).GetThumbnailAsync(ThumbnailMode.PicturesView, 50) });
            emotionList.Add(new StorageItemThumbnailClass { Name = EmotionEnum.Afraid.ToString(), Thumbnail = await (await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/EmotionIcons/afraid.png"))).GetThumbnailAsync(ThumbnailMode.PicturesView, 50) });
            emotionList.Add(new StorageItemThumbnailClass { Name = EmotionEnum.Happy.ToString(), Thumbnail = await (await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/EmotionIcons/happy.png"))).GetThumbnailAsync(ThumbnailMode.PicturesView, 50) });
            emotionList.Add(new StorageItemThumbnailClass { Name = EmotionEnum.Neutral.ToString(), Thumbnail = await (await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/EmotionIcons/neutral.png"))).GetThumbnailAsync(ThumbnailMode.PicturesView, 50) });
            emotionList.Add(new StorageItemThumbnailClass { Name = EmotionEnum.Sad.ToString(), Thumbnail = await (await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/EmotionIcons/sad.png"))).GetThumbnailAsync(ThumbnailMode.PicturesView, 50) });
            emotionList.Add(new StorageItemThumbnailClass { Name = EmotionEnum.Surprised.ToString(), Thumbnail = await (await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/EmotionIcons/surprised.png"))).GetThumbnailAsync(ThumbnailMode.PicturesView, 50) });
        }

Here is the StorageItemThumbnailClass -

public class StorageItemThumbnailClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private StorageItemThumbnail _thumbnail;
    private string _name;

    public StorageItemThumbnail Thumbnail
    {
        get { return _thumbnail; }
        set
        {
            _thumbnail = value;
            // Call OnPropertyChanged whenever the property is updated
            OnPropertyChanged("Thumbnail");
        }
    }

    // Create the OnPropertyChanged method to raise the event
    protected void OnPropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    public String Name
    {
        get { return _name; }
        set
        {
            _name = value;
            // Call OnPropertyChanged whenever the property is updated
            OnPropertyChanged("Name");
        }
    }
}

And here is the converter-

class ImagetoThumbnailConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        BitmapImage image = null;
        if (value != null)
        {
            if (value.GetType() != typeof(StorageItemThumbnail))
            {
                throw new ArgumentException("Expected a thumbnail");
            }
            StorageItemThumbnail thumbnail = (StorageItemThumbnail)value;
            image = new BitmapImage();
            image.SetSource(thumbnail);
        }
        return (image);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

Upvotes: 1

Views: 130

Answers (1)

Nikhil Gupta
Nikhil Gupta

Reputation: 172

I was able to resolve this issue. The ComboBox performs UI virtualization, and images in the ComboBox’s virtualized panel were removed when scrolled out of view. When scrolled back, converter of the removed image was called again and the image source was reset. Hence, the stream used as source needed to be set to the start position for reuse.

Converter-

StorageItemThumbnail thumbnail = (StorageItemThumbnail)value;
thumbnail.Seek(0);
image = new BitmapImage();
image.SetSource(thumbnail);

Upvotes: 1

Related Questions