У меня есть функция, которая берет объект из файла хранилища и создает его эскиз. Эта функция находится в значении конвертера, так как у нас есть более 10.000 файлов, которые будут показаны в медиа галерее. Миниатюра будет сгенерирована в файле, когда миниатюра еще не создана для файла хранения.
Проблема в том, что пользовательский интерфейс GridView не обновляется после создания эскиза / обновления объекта. Миниатюра будет отображаться только в том случае, если я прокручиваю достаточно далеко и снова прокручиваю вверх.
public class MediaFile : INotifyPropertyChanged
{
// Declare the event
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private ImageSource _thumbnail = null;
public ImageSource Thumbnail
{
get { return _thumbnail; }
set
{
_thumbnail = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("Thumbnail");
}
}
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChanged(this, e);
}
// Create the OnPropertyChanged method to raise the event
// The calling member's name will be used as the parameter.
protected void OnPropertyChanged(string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
Это класс так называемого MediaFile. Как вы можете видеть, я уже реализовал событие измененного свойства.
<DataTemplate x:Key="GridMedia_DataTemplate" x:DataType="MediaFile">
<Grid Style="{StaticResource Faves_Grid}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Grid.Row="1" Grid.RowSpan="2" Margin="0 14 0 -12" Grid.ColumnSpan="2" HorizontalAlignment="Stretch" Stretch="UniformToFill" VerticalAlignment="Stretch" Source="{x:Bind Converter={StaticResource ThumbnailGenerator}, Mode=OneWay}"/>
</Grid>
</DataTemplate>
Вот шаблон данных для вида сетки. Как видите, для ImageSource мы используем конвертер, чтобы получить / сгенерировать миниатюру.
public object Convert(object value, Type targetType, object parameter, string language)
{
try
{
if(value is MediaFile)
{
MediaFile file = value as MediaFile;
//generate Thumbnail
int width = 160;
int height = 90;
var pathFileTemp = $@"{FileLocations.MediaPath}";
try
{
StorageFile originalFile = StorageFile.GetFileFromPathAsync(pathFileTemp + file.Id).AsTask().Result;
if (originalFile != null)
{
//check extention
if (file.Extension.ToLower().Contains("pdf"))
{
GetThumbnailForPDF(file).GetAwaiter();
return file.Thumbnail;
}
else if (file.Extension.ToLower().Contains("jpg") ||
file.Extension.ToLower().Contains("gif") ||
file.Extension.ToLower().Contains("png") ||
file.Extension.ToLower().Contains("jpeg"))
{
GetThumbnailForImage(file).GetAwaiter();
return file.Thumbnail;
}
}
return new BitmapImage(new Uri("ms-appx:///Assets/Icon/placeholder_img.jpg", UriKind.Absolute));
}
catch (Exception)
{
return new BitmapImage(new Uri("ms-appx:///Assets/Icon/placeholder_img.jpg", UriKind.Absolute));
}
}
return null;
}
catch (Exception)
{
return null;
}
}
На данный момент мы создаем только миниатюру для PDF и изображений. Помимо этого мы вернем заполнитель миниатюру.
<controls1:AdaptiveGridView Grid.Row="1" DesiredWidth="288" x:Name="ListView_MediaLibrary" Grid.ColumnSpan="4" ItemTemplate="{StaticResource GridMedia_Adaptive__DataTemplate}" Margin="0 0 -8 -20" SelectionChanged="ListView_MediaLibrary_SelectionChanged" ItemsSource="{Binding Source={StaticResource mediaFilesSource}, Mode=OneWay}">
</controls1:AdaptiveGridView>
И вот как мы связываем список с GridView.