0

I'm trying to show a set of pictures from a directory in a ListBox. This ListBox should be updated when I select another directory. The following code does not work correcty and I don't know why. LoadImages() works correctly because _selectedImageList has the elements contained in the selected directory but the ListBox does not show anything.

XAML:

<ListBox x:Name="ListBoxSnapshots" ItemsSource="{Binding SelectedImageList, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Focusable="False" BorderThickness="0" SelectionMode="Single" HorizontalContentAlignment="Left" VerticalContentAlignment="Stretch" SelectionChanged="ListBoxSnapshots_SelectionChanged" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Disabled" SelectedIndex="0" >
   <ListBox.ItemTemplate>
       <DataTemplate>
           <StackPanel>
               <Image Source="{Binding}" Stretch="Fill" />
           </StackPanel>
       </DataTemplate>
   </ListBox.ItemTemplate>
   <ListBox.ItemsPanel>
       <ItemsPanelTemplate>
            <WrapPanel IsItemsHost="True" Orientation="Horizontal" />
       </ItemsPanelTemplate>
   </ListBox.ItemsPanel>
</ListBox>

My ViewModel:

private ObservableCollection<ImageSource> _selectedImageList = new ObservableCollection<ImageSource>();

public ObservableCollection<ImageSource> SelectedImageList
{
   get { return _selectedImageList; }
   set { _selectedImageList = value; }
}

private void LoadImages()
{
   _selectedImageList = new ObservableCollection<ImageSource>();

   DirectoryInfo aSnapshotTempDir = new DirectoryInfo(@"..\..\Images");

   foreach (FileInfo aFile in aSnapshotTempDir.GetFiles("*.jpg"))
   {
       Uri uri = new Uri(aFile.FullName);
       _selectedImageList.Add( new BitmapImage( uri ) );
   }
}

I'm trying to do something like that ( Displaying Images in ListView (or something better!) in WPF MVVM using databinding ) but something is wrong in my code.

Thanks.

Community
  • 1
  • 1
Jafuentes
  • 365
  • 2
  • 6
  • 13
  • 2
    Why you are using _selectedImageList as your ItemsSource. It is private. – AnjumSKhan Dec 14 '15 at 11:02
  • I have updated my XAML with `ItemsSource="{Binding SelectedImageList, UpdateSourceTrigger=PropertyChanged}"` and my code behing with `private void LoadImages() { _selectedImageList.Clear(); ...`. it works. – Jafuentes Dec 14 '15 at 11:10
  • You have to call `LoadImages` **before** you set `DataContext` or, if you do it after, notify what you just change it (call `OnPropertyChanged` at the end of `LoadImage` method). Then it should work (rest of code seems ok). – Sinatr Dec 14 '15 at 11:14

1 Answers1

1

There are two problems :
I. You are not binding to public property exposed for your ObservableCollection.

ItemsSource="{Binding SelectedImageList"}

II. The problem is here that you are initializing the ObservableCollection object every time in LoadImages method with a new reference and due to binding of ListBox breaks.
This can be resolved by two approach :
1. Notify View that collection has changed through PropertyChanged (INotifyPropertyChanged).

public ObservableCollection<ImageSource> SelectedImageList
{
   get { return _selectedImageList; }
   set { _selectedImageList = value; 
       SendPropertyChanged("SelectedImageList"); // suppose you have implemented INotifyPropertyChanged interface in this method.
       }
}
  1. Clear the collection and add new items.

     private void LoadImages()
     {
         _selectedImageList.Clear();
         DirectoryInfo aSnapshotTempDir = new DirectoryInfo(@"..\..\Images");
         foreach (FileInfo aFile in aSnapshotTempDir.GetFiles("*.jpg"))
         {
             Uri uri = new Uri(aFile.FullName);
            _selectedImageList.Add( new BitmapImage( uri ) );
          }
     }
    

As per best practice, you should go with step 2 as initializing an observable Collection refers to new address in heap and notifying to view to bind the new collection up-fresh in main thread will be resource centric for performance.

user1672994
  • 10,509
  • 1
  • 19
  • 32