Graeme_Grant
ObservableCollection<Picture> pictures= new ObservableCollection<Picture>();lb.ItemsSource = pictures;
Три трюка с привязкой и тем
ObservableCollection
класс должен инициализировать его только один раз. Повторная инициализация его, как вы находитесь выше, нарушит привязку к коллекции.
Во-вторых, вам нужно только один раз установить свойство ListBox ItemsSource. Обычно оно задается в XAML, и, для кода, привязка кода к странице XAML :
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
Поэтому, чтобы исправить свой код, вам нужно сделать следующее:
private void paste(IEnumerable<MyPicture> newPictures)
{
MyPictures.Clear();
foreach (var item in newPictures)
{
MyPictures.Add(item);
}
}
И
Pictures
коллекция должна быть выставлена как свойство для того, чтобы Listbox правильно ее видел:
public ObservableCollection<MyPicture>
MyPictures{ get; }
= new ObservableCollection<MyPicture>();
Затем правильно использовать:
private void button1_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog op = new OpenFileDialog()
{
Title = "Select picture(s)",
Filter = "All supported graphics|" +
"*.jpg;*.jpeg;*.png|" +
"JPEG (*.jpg;*.jpeg)|" +
"*.jpg;*.jpeg|" +
"Portable Network Graphic (*.png)" +
"|*.png",
InitialDirectory = Environment.GetFolderPath(
Environment.SpecialFolder.MyPictures),
Multiselect = true
};
if (op.ShowDialog() == true)
{
paste(op.FileNames.Select(f => new MyPicture
{
Url = new Uri(f, UriKind.Absolute),
Title = System.IO.Path.GetFileName(f)
}));
}
}
Примечание:
MyPicture
класс - это ваш собственный объект данных. Что-то вроде:
public class MyPicture
{
public Uri Url { get; set; } // filename of image
public string Title {get; set; }
}
Далее вам нужно исправить свой XAML. Вот вам пример:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Content="Load Images"
Margin="10" Padding="10 5"
HorizontalAlignment="Center"
Click="Button_Click"/>
<ListBox ItemsSource="{Binding MyPictures}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Grid.Row="1" Margin="10">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid MaxWidth="200" Margin="10">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Source="{Binding Url}" />
<TextBlock Text="{Binding Title}"
HorizontalAlignment="Center"
Grid.Row="1" Margin="0 5"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Если вы хотите редактировать свойства с помощью системы привязки, то вам нужно будет реализовать
INotifyPropertyChanged
интерфейс для
MyPicture
класс. Вы можете прочитать больше здесь:
Привязка данных (WPF) | Microsoft Docs[
^]
[обновление] Вот полное кодовое решение:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
public ObservableCollection<MyPicture> MyPictures { get; }
= new ObservableCollection<MyPicture>();
private void Button_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog op = new OpenFileDialog()
{
Title = "Select picture(s)",
Filter = "All supported graphics|" +
"*.jpg;*.jpeg;*.png|" +
"JPEG (*.jpg;*.jpeg)|" +
"*.jpg;*.jpeg|" +
"Portable Network Graphic (*.png)" +
"|*.png",
InitialDirectory = Environment.GetFolderPath(
Environment.SpecialFolder.MyPictures),
Multiselect = true
};
if (op.ShowDialog() == true)
{
paste(op.FileNames.Select(f => new MyPicture
{
Url = new Uri(f, UriKind.Absolute),
Title = System.IO.Path.GetFileName(f)
}));
}
}
private void paste(IEnumerable<MyPicture> newPictures)
{
MyPictures.Clear();
foreach (var item in newPictures)
{
MyPictures.Add(item);
}
}
}
public class MyPicture
{
public Uri Url { get; set; } // filename of image
public string Title { get; set; }
}