wpfmvvmdata-bindinglistboxlistboxitem

Populate a WPF Listbox with Images


I am trying to populate a listbox with some images (3 of them), the images are coming from within my application, but I cannot seem to get this to work. I need to know which image is selected so that I can update my app theme accordingly.

I am trying to avoid code behind if I possibly can. TIA

Current xaml:

<ListBox ItemContainerStyle="{DynamicResource ThemeListBoxItem}"
         ItemsSource="{Binding Themes}"
         SelectedItem="{Binding SelectedTheme, Mode=TwoWay}"
         Style="{DynamicResource ThemeListBox}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Image Source="{Binding Theme.PreviewImagePath}" />
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

ItemSource Themes:

Public ITheme[] Themes => _themeService.Themes;

ThemeService:

Public ThemeService()
{
   Themes = new[]
   {
      DarkTheme,
      DefaultTheme,
      MonoTheme
   };
}

Public ITheme[] Themes { get; }

    public ITheme DarkTheme { get; } = new Theme("Dark Theme",
                                                 "pack://application:,,,/MyApp;component/Themes/DarkTheme.xaml",
                                                 "pack://application:,,,/MyApp;component/Assets/Media/BG_DarkTheme.png");

    public ITheme MonoTheme { get; } = new Theme("Monochrome Theme",
                                                 "pack://application:,,,/MyApp;component/Themes/MonochromeTheme.xaml",
                                                 "pack://application:,,,/MyApp;component/Assets/Media/BG_Monochrome.png");

    public ITheme DefaultTheme { get; } = new Theme("Light Theme",
                                                    "pack://application:,,,/MyApp;component/Themes/DefaultTheme.xaml",
                                                    "pack://application:,,,/MyApp;component/Assets/Media/BG_LightTheme.png");

Theme:

public interface ITheme
{
    string DisplayName { get; }

    string PreviewImagePath { get; }

    string ThemeName { get; }

    string ThemePath { get; }
}

public Theme(string name, string themePath, string previewImagePath)
{
    DisplayName = name;
    PreviewImagePath = previewImagePath;
    ThemePath = themePath;
}

Currently, my Listbox is populated with 3 items, but there is no image loaded (Green square indicates SelectedItem): Screenshot of Listbox, Green square indicates SelectedItem


Solution

  • The Binding Path is incorrect. It should be

    <Image Source="{Binding PreviewImagePath}"/>
    

    because the DataContext of the Image is the associated element from the Themes collection, i.e. a Theme object.


    Also make sure that a potential ControlTemplate in the ItemContainerStyle contains a ContentPresenter so that the ItemTemplate is actually used.


    And ensure that the Build Action of the image files is set to Resource.