WPF:带有文件夹中图像的 ListView
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16498284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF: ListView with Images from a folder
提问by user2352164
I'm sort of new to WPF, but I have to do this and it's taking a lot of my time. I've searched for a solution but there are many alternative solutions and I honestly don't understand most of this. I have this XAML code:
我对 WPF 有点陌生,但我必须这样做,而且这花费了我很多时间。我已经寻找了一个解决方案,但有很多替代解决方案,老实说,我大部分都不明白。我有这个 XAML 代码:
<ListView Name="Thumbnails">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Height="30" Width="30" Margin="5"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
As well as this codebehind:
以及这个代码隐藏:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
DirectoryInfo folder = new DirectoryInfo(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\SlikeSportista\");
FileInfo[] images = folder.GetFiles("*.jpg");
foreach (FileInfo img in images)
{
Thumbnails.Items.Add(img);
}
}
I've also tried this line of code in the foreach loop:
我也在 foreach 循环中尝试过这行代码:
Thumbnails.Items.Add(System.Drawing.Image.FromFile(img.FullName));
In both cases the items are added, but the images are not displayed correctly, or rather, at all. You can select them, and there are the same amount of elements as there are in the folder, but there is no display.
在这两种情况下,都添加了项目,但图像显示不正确,或者根本没有显示。您可以选择它们,并且与文件夹中的元素数量相同,但没有显示。
Another question (less important one) would be how to display the images in squares instead of rows. Basically I want to have about 4 or so images per row, but now I have only 1 element per row, stretched all the way (although I can't see what is being displayed).
另一个问题(不太重要的一个)是如何以正方形而不是行显示图像。基本上我希望每行有大约 4 个左右的图像,但现在每行只有 1 个元素,一直拉伸(尽管我看不到正在显示的内容)。
回答by Clemens
In your first attempt, you're adding FileInfoobjects to the ListView's items collections. These aren't automatically converted to ImageSourceitems, as required by the binding in your DataTemplate. Add the FileInfo's FullNameinstead:
在您的第一次尝试中,您将FileInfo对象添加到 ListView 的项目集合。这些不会ImageSource按照 DataTemplate 中的绑定要求自动转换为项目。FullName改为添加 FileInfo :
foreach (FileInfo img in images)
{
Thumbnails.Items.Add(img.FullName);
}
In your second attempt the problem is that you add instances of System.Drawing.Image, which is not part of WPF, but WinForms, and will also not be converted automatically. You may use BitmapImageinstead:
在您的第二次尝试中,问题是您添加了 的实例System.Drawing.Image,它不是 WPF 的一部分,而是 WinForms,并且也不会自动转换。您可以BitmapImage改用:
foreach (FileInfo img in images)
{
Thumbnails.Items.Add(new BitmapImage(new Uri(img.FullName)));
}
The difference between both solutions is that in the second one you manually create image objects, whereas the first one relies on automatic conversion from stringto ImageSource, which is built into WPF as a TypeConverter.
两种解决方案之间的区别在于,在第二个解决方案中您手动创建图像对象,而第一个依赖于从stringto 的自动转换ImageSource,它作为 TypeConverter 内置到 WPF 中。
A solution for your second question would be to replace the ListView's ItemsPanel, perhaps by a UniformGrid:
您的第二个问题的解决方案是替换 ListView 的ItemsPanel,也许是UniformGrid:
<ListView Name="Thumbnails">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="4"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
...
</ListView>
回答by Jonathan Perry
As a general rule, you should keep in mind that adding images in the code-behind file (.xaml.cs file) is bad practice. In WPF there is a very widely used and common design pattern called MVVM (Model-View-ViewModel) which you should familiarize with and use. In your case, you should have had a ViewModel class containing an IEnumerable<BitmapImage>property that contains the images you wish to display in your ListView.
作为一般规则,您应该记住在代码隐藏文件(.xaml.cs 文件)中添加图像是不好的做法。在 WPF 中,有一种使用非常广泛且常见的设计模式,称为 MVVM(模型-视图-视图模型),您应该熟悉并使用它。在您的情况下,您应该有一个 ViewModel 类,其中包含一个IEnumerable<BitmapImage>属性,该属性包含您希望在ListView.
For example, let's say your ViewModel class is called ImagesViewModel and your view is ImagesView:
例如,假设您的 ViewModel 类名为 ImagesViewModel,而您的视图为 ImagesView:
ImagesViewModelwill have a property called:
ImagesViewModel将有一个名为:
ObservableCollection<BitmapImage> Images
ObservableCollection<BitmapImage> Images
ImagesViewwill contain:
ImagesView将包含:
<ListView Name="Thumbnails" ItemsSource="{Binding Images}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="4"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
...
Now, if you add / remove images to Images, they will be automatically added / removed from your list view (you have to implement the INotifyPropertyChangedinterface in your view model and you're done).
现在,如果您向图像添加/删除图像,它们将自动从您的列表视图中添加/删除(您必须INotifyPropertyChanged在您的视图模型中实现该接口,然后您就完成了)。

