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