Reputation:
I am trying to put the entire collection of images in a user's Pictures folder into an ObservableCollection
(Images). If I get only .png's it works fine, but if I also try to get .jpg's it throws a SystemOutOfMemory
exception. I am using the following code:
String picturesPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
String[] files = Directory.GetFiles(picturesPath, "*", SearchOption.AllDirectories);
foreach (String file in files)
{
ImageInfo newImage = new ImageInfo() { Id = Guid.NewGuid().ToString(), Path = file }; //Id and Path are properties of newImage, defined by the ImageInfo class
if (file.EndsWith(".png") || file.EndsWith(".jpg")) Images.Add(newImage);
}
EDIT: I am using the following code to add the images to a StackPanel
. (RibbonButton
is a custom component).
foreach (ImageInfo image in startup.Images)
{
Image newImage = new Image();
newImage.Source = new BitmapImage(new Uri(image.Path, UriKind.RelativeOrAbsolute));
RibbonButton newRibbonButton = new RibbonButton();
RibbonButton.SetCornerRadius(newRibbonButton, new CornerRadius(0));
SolidColorBrush brush = new SolidColorBrush(Colors.DarkGray);
RibbonButton.SetIsPressedBackground(newRibbonButton, brush);
newRibbonButton.Content = newImage;
newRibbonButton.ToolTip = image.Path;
newRibbonButton.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Center;
newRibbonButton.Margin = new Thickness(5);
newRibbonButton.Width = 100;
newRibbonButton.Height = 60;
imagesListStackPanel.Children.Add(newRibbonButton);
}
EDIT: The OnPropertyChanged
handler:
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region OnPropertyChanged
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion OnPropertyChanged
Can anyone tell me why this is happening? Thanks
Upvotes: 0
Views: 66
Reputation: 101681
Directory.GetFiles
loads all file names into memory. You can use EnumerateFiles
if you don't need all of them:
foreach(var file in Directory.EnumerateFiles(picturesPath, "*", SearchOption.AllDirectories))
Or via LINQ
you can make it more cleaner:
var images = Directory.EnumerateFiles(picturesPath, "*", SearchOption.AllDirectories)
.Where(f => Path.GetExtension(f) == ".png" || Path.GetExtension(f) == ".jpg")
.Select(file => new ImageInfo()
{
Id = Guid.NewGuid().ToString(),
Path = file
});
foreach(var img in images)
{
Images.Add(img);
}
Upvotes: 4
Reputation: 68640
To add to Selmen22's solution, you can restructure your logic to avoid loading images and creating instances of ImageInfo
that you're not interested in.
foreach (var file in Directory.EnumerateFiles(picturesPath, "*", SearchOption.AllDirectories))
{
if (file.EndsWith(".png") || file.EndsWith(".jpg"))
{
ImageInfo newImage = new ImageInfo() { Id = Guid.NewGuid().ToString(), Path = file };
Images.Add(newImage);
}
}
Upvotes: 0