Reputation: 19
Wandering If I can get help, the combobox lists hdds, when clicked I would like the listbox to list bitmap image thumbnails from that corrosponding hdd (each selected HDD is converted to a string which I hope to use as the address to get the thumbnails, I originally had help to get this to work with just full images but because thats slow I'm experimenting with thumbnails, so far I get no errors but nothing shows in the listbox and Im sure I have binded
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void Window_Loaded(object sender, RoutedEventArgs e) //Window Loaded Event
{
///Load Avaliable Drives Into ComboBox
string[] drives = Environment.GetLogicalDrives(); //Drive Letters, Into A String Array
foreach (string drive in drives)
{
HDDSelectionBox.Items.Add(drive); //Adds Each Drive Letter As A Combox Box Item
}
string root = (HDDSelectionBox.SelectedItem.ToString()); //Contains Directory Path For Images
string[] supportedExtensions = new[] { ".bmp", ".jpeg", ".jpg", ".png", ".tiff" };
var files = System.IO.Directory.EnumerateFiles(root, "*.*").Where(s => supportedExtensions.Contains(System.IO.Path.GetExtension(s).ToLower()));
List<Photos> images = new List<Photos>();
if (HDDSelectionBox.SelectedItem != null) //If a item has been selected
{
foreach (var file in files)
{
Photos id = new Photos()
{
Path = file,
FileName = System.IO.Path.GetFileName(file),
Extension = System.IO.Path.GetExtension(file)
};
BitmapImage img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
img.UriSource = new Uri(file, UriKind.Absolute);
img.EndInit();
id.Width = img.PixelWidth;
id.Height = img.PixelHeight;
// I couldn't find file size in BitmapImage
FileInfo fi = new FileInfo(file);
id.Size = fi.Length;
images.Add(id);
}
ImageListBox.ItemsSource = images;
}
}
}
public class Photos
{
/// <summary>
/// A name for the image, not the file name.
/// </summary>
public string Name { get; set; }
/// <summary>
/// A description for the image.
/// </summary>
public string Description { get; set; }
/// <summary>
/// Full path such as c:\path\to\image.png
/// </summary>
public string Path { get; set; }
/// <summary>
/// The image file name such as image.png
/// </summary>
public string FileName { get; set; }
/// <summary>
/// The file name extension: bmp, gif, jpg, png, tiff, etc...
/// </summary>
public string Extension { get; set; }
/// <summary>
/// The image height
/// </summary>
public int Height { get; set; }
/// <summary>
/// The image width.
/// </summary>
public int Width { get; set; }
/// <summary>
/// The file size of the image.
/// </summary>
public long Size { get; set; }
}
}
Upvotes: 0
Views: 111
Reputation: 16119
First create a base model that you can use to do property notifications (the XAML controls need this in order to respond to changes:
public abstract class ObservableObject : INotifyPropertyChanged
{
protected ObservableObject()
{
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged<T>(Expression<Func<T>> propertyExpresion)
{
var property = (MemberExpression)propertyExpresion.Body;
this.OnPropertyChanged(property.Member.Name);
}
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
protected void SetValue<T>(ref T refValue, T newValue, Expression<Func<T>> propertyExpresion)
{
if (!object.Equals(refValue, newValue))
{
refValue = newValue;
this.OnPropertyChanged(propertyExpresion);
}
}
protected void SetValue<T>(ref T refValue, T newValue, Action valueChanged)
{
if (!object.Equals(refValue, newValue))
{
refValue = newValue;
valueChanged();
}
}
protected void SetValue<T>(ref T refValue, string propertyName, T newValue)
{
if (!object.Equals(refValue, newValue))
{
refValue = newValue;
this.OnPropertyChanged(propertyName);
}
}
}
Now create a model that enumerates your hard drive and images and creates thumbnails:
public class ImagesModel : ObservableObject
{
private ObservableCollection<string> _HardDrives;
public ObservableCollection<string> HardDrives
{
get {return this._HardDrives;}
set {this._HardDrives = value; OnPropertyChanged(() => this.HardDrives);}
}
private string _CurrentDrive;
public string CurrentDrive
{
get {return this._CurrentDrive;}
set {
this._CurrentDrive = value;
OnPropertyChanged(() => this.CurrentDrive);
// enumerate files in this drives
string[] supportedExtensions = new[] { ".bmp", ".jpeg", ".jpg", ".png", ".tiff" };
this.Images = new ObservableCollection<PhotoModel>(
System.IO.Directory.EnumerateFiles(value, "*.*")
.Where(s => supportedExtensions.Contains(System.IO.Path.GetExtension(s).ToLower()))
.Select(filename => new PhotoModel(filename)));
}
}
private ObservableCollection<PhotoModel> _Images;
public ObservableCollection<PhotoModel> Images
{
get {return this._Images;}
set {this._Images = value; OnPropertyChanged(() => this.Images);}
}
private PhotoModel _CurrentImage;
public PhotoModel CurrentImage
{
get {return this._CurrentImage;}
set {this._CurrentImage = value; OnPropertyChanged(() => this.CurrentImage);}
}
public ImagesModel()
{
this.HardDrives = new ObservableCollection<string>(Environment.GetLogicalDrives());
}
}
public class PhotoModel : ObservableObject
{
private string _FileName;
public string FileName
{
get {return this._FileName;}
private set { this._FileName = value; OnPropertyChanged(() => this.FileName);}
}
private ImageSource _Image;
public ImageSource Image {
get {return this._Image;}
private set {this._Image = value;OnPropertyChanged(() => this.Image);}
}
public PhotoModel(string filename)
{
this.FileName = filename;
BitmapImage img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
img.UriSource = new Uri(filename, UriKind.Absolute);
img.DecodePixelWidth = 64; // or whatever
img.EndInit();
this.Image = img;
}
}
Obviously you'll need to create an instance of this class and assign it to your windows's DataContext:
public MainWindow()
{
InitializeComponent();
this.DataContext = new ImagesModel();
}
Finally add your ComboBox and ListBox to the window, set up your bindings and override the ListBox item template to display the images:
<Grid>
<ComboBox ItemsSource="{Binding HardDrives}" SelectedValue="{Binding CurrentDrive}" HorizontalAlignment="Left" Margin="27,35,0,0" VerticalAlignment="Top" Width="120"/>
<ListBox ItemsSource="{Binding Images}" SelectedValue="{Binding CurrentImage}" HorizontalAlignment="Left" Height="212" Margin="27,87,0,0" VerticalAlignment="Top" Width="188">
<ListBox.ItemTemplate>
<DataTemplate>
<Image Width="64" Height="64" Source="{Binding Image}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Upvotes: 1