Home > Software design >  How to use image files dynamically at runtime as button content in WPF?
How to use image files dynamically at runtime as button content in WPF?

Time:12-22

My current implementation loops through PNG files in a folder, and create a number of buttons with background images from the files in that folder.

For this to work, at design time in Visual Studio, I have to set the build action of every PNG in that folder to resource, and then use something as following

button.Content = new Image { 
             Source = new BitmapImage(new Uri(product.ImageLink ?? "",UriKind.Relative)),
             Stretch = Stretch.Fill 
             }

The problem with this approach is that every time a new PNG file is added to the folder, I will need to set the build action of that PNG file to resource and re-publish the solution.

Is it instead possible to loop through all the PNG files at runtime in a folder to use them as button content ?

CodePudding user response:

Simply enumerate the folder and add the file paths of interest to a List or ObservableCollection and bind it to a ListBox (or any ItemsControl of choice). Define a DataTemplate to render the image buttons. You can use the FileSystemWatcher to observe directories for changes.

MainWindow.xaml.cs

public partial class MainWindow : Window
{
  private const string ImageFolderPath = @"C:\SomeImages";
  public ObservableCollection<string> ImageFilePaths { get; } = new ObservableCollection<string>();

  private void OnClick(object sender, RoutedEventArgs e)
  {
    this.ImageFilePaths.Clear();
    var directoryInfo = new DirectoryInfo(ImageFolderPath);
    var enumerationOptions = new EnumerationOptions();
    foreach (string imageFilePath in directoryInfo.EnumerateFiles("*", enumerationOptions)
      .Where(fileInfo => fileInfo.Extension is ".png" or ".jpg")
      .Select(fileInfo => fileInfo.FullName))
    {
      this.ImageFilePaths.Add(imageFilePath);
    }
  }
}

MainWindow.xaml

<Window>
  <Button Content="Load Images" 
          Click="OnClick" />
  <ListBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=ImageFilePaths}">
    <ListBox.ItemTemplate>
      <DataTemplate>
        <Button>
          <Image Height="96"
                 Width="96"
                 Source="{Binding}" />
        </Button>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</Window>
  • Related