Czas żeby wykorzystać napisaną w ostatnim poście kontrolkę do wyświetlania obrazków przedstawioną w poprzednim poście. Na razie wykorzystywana będzie jedynie podczas przeglądania struktury dysku. Sprzężenie między aktualnym katalogiem a zdjęciami również będzie tymczasowe.
Aby w prosty sposób móc przekazać listę zdjęć do kontrolki ImageListView wystawiona na zewnątrz niej zostanie jedna DependencyProperty typu ObservableCollecion<Photo>. Dzięki temu bindowanie może być zrobione z poziomu XAML'a.
public ObservableCollection<Photo> Photos
{
get
{
return (ObservableCollection<Photo>)GetValue(PhotosProperty);
}
set
{
SetValue(PhotosProperty, value);
}
}
public static readonly DependencyProperty PhotosProperty = DependencyProperty.Register(
PhotosPropertyName,
typeof(ObservableCollection<Photo>),
typeof(ImageListView),
new PropertyMetadata(new ObservableCollection<Photo>(), new PropertyChangedCallback(OnPhotosListChanged)));
Przy każdej zmianie zawartości listy zdjęć zostanie wywołana funkcja OnPhotosListChanged. Jej jedynym zadaniem będzie wysłanie komunikatu poprzez niedawno stworzoną statyczną klasę AppMessages.
private static void OnPhotosListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
AppMessages.PhotoSourceChangedMessage.Send(e.NewValue as ObservableCollection<Photo>);
}
Wiadomość ta jest odbierana w konstruktorze kontrolki i po prostu przypisuje nowo otrzymaną listę to właściwości użytej do przechowywania listy:
Do przeglądania zdjęć na dysku potrzebne jest jedynie, aby lista zdjęć była odświeżona za każdym razem, gdy zmieni się zaznaczony folder. Można to osiągnąć przez zbindowanie aktualnie wybranego katalogu z kontrolki DirectoryTreeView do właściwości Photos kontrolki ImageListView.
AppMessages.PhotoSourceChangedMessage.Register(this, p => Photos = p);
Do przeglądania zdjęć na dysku potrzebne jest jedynie, aby lista zdjęć była odświeżona za każdym razem, gdy zmieni się zaznaczony folder. Można to osiągnąć przez zbindowanie aktualnie wybranego katalogu z kontrolki DirectoryTreeView do właściwości Photos kontrolki ImageListView.
<my:ImageListView Photos="{Binding CurrentDirectory, Converter={StaticResource DirectoryToPhotosConverter}, ElementName=directoryTreeView}"/>
Oczywiście nie zrzucamy na kontrolkę wyświetlającą odpowiedzialności z pobranie listy zdjęć z dysku. Dlatego też użyty jest konwerter zamieniający ścieżkę do katalogu na listę obiektów Photo, wskazujących na zdjęcia z tego katalogu.
[ValueConversion(typeof(string), typeof(ObservableCollection<Photo>))]
public class DirectoryToPhotosConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string str = value as string;
if (str != null)
{
IList<Photo> photos = ImageLoader.GetListOfPhotosFromPath(str);
if (photos != null)
return new ObservableCollection<Photo>(photos);
}
return new ObservableCollection<Photo>();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Konwerter ten wykorzystuje metodę GetListOfPhotosFromPath z klasy ImageLoader:
public class ImageLoader
{
public static List<Photo> GetListOfPhotosFromPath(string path)
{
List<Photo> result = new List<Photo>();
if (Directory.Exists(path))
{
result.AddRange(getPhotosByExt(path, "*.jpg"));
result.AddRange(getPhotosByExt(path, "*.jpeg"));
result.AddRange(getPhotosByExt(path, "*.png"));
result.AddRange(getPhotosByExt(path, "*.gif"));
}
return result;
}
private static List<Photo> getPhotosByExt(string path, string ext)
{
List<Photo> result = new List<Photo>();
string[] files = Directory.GetFiles(path, ext);
foreach (var f in files)
{
result.Add(new Photo
{
Path = f,
Description = Path.GetFileName(f)
});
}
return result;
}
}
Jest to trochę naiwna implementacja zakładająca, że istnieją tylko cztery rodzaje plików graficznych, ale to sprawdzenia poprawności działania w zupełności wystarcza.
Po połączeniu tych elementów można już przeglądać katalogi w poszukiwaniu zdjęć :P
Brak komentarzy:
Prześlij komentarz