我想从文件夹向listbox显示图片,但在WPF中我是初学者所以我找到了这个教程:http://www.codeproject.com/Articles/18561/Custom-ListBox-Layout-in-WPF
XAML :
<UserControl.Resources>
<Style TargetType="{x:Type ListBox}">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="4"
CornerRadius="5" Margin="6"
>
<Image
Source="{Binding Path=UriSource}"
Stretch="Fill"
Width="100" Height="120"
/>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<UserControl.DataContext>
<ObjectDataProvider
ObjectType="{x:Type local:UserControlTest}"
MethodName="LoadImages" />
</UserControl.DataContext>
<ListBox x:Name="listBox" ItemsSource="{Binding}" />
代码背后:
public static List<BitmapImage> LoadImages()
{
List<BitmapImage> robotImages = new List<BitmapImage>();
DirectoryInfo robotImageDir = new DirectoryInfo(@"..\folder");
foreach (FileInfo robotImageFile in robotImageDir.GetFiles("*.jpeg"))
{
Uri uri = new Uri(robotImageFile.FullName);
robotImages.Add(new BitmapImage(uri));
}
return robotImages;
}
但我有一个错误:
抛出了'System.StackOverflowException'类型的异常。
与此同时,我尝试打开例外设置( Ctrl + Alt + E )并选中所有复选框,但仍然没有。
修改
我试图在Code Behind中评论我的方法并且错误是相同的,因此问题将出现在XAML中
答案 0 :(得分:0)
有一件事就是这一行:
<Image Source="{Binding Path=UriSource}"/>
由于DataContext本身应该是BitmapImage
,请尝试将其替换为
<Image Source="{Binding Path=.}"/>
递归是由MainWindow的构造函数引起的。 ObjectDataProvider生成一个新实例,它生成一个新的ObjectDataProvider等...
将您的LoadImages方法放在一个单独的类中。
public class ImageLoader
{
public List<BitmapImage> LoadImages()
{
List<BitmapImage> robotImages = new List<BitmapImage>();
DirectoryInfo robotImageDir = new DirectoryInfo(@"C:\Users\Public\Pictures\Sample Pictures");
foreach (FileInfo robotImageFile in robotImageDir.GetFiles("*.jpg"))
{
Uri uri = new Uri(robotImageFile.FullName);
robotImages.Add(new BitmapImage(uri));
}
return robotImages;
}
}
将您的XAML更改为
<ListBox ItemsSource="{Binding}">
<ListBox.DataContext>
<ObjectDataProvider ObjectType="local:ImageLoader" MethodName="LoadImages"/>
</ListBox.DataContext>
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Width="100" Height="100" Stretch="Uniform"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
答案 1 :(得分:0)
将LoadImages方法放入静态类(而不是在usercontrol类中),而是使用静态类的名称。
代码背后:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public static class ImageLoader
{
public static List<BitmapImage> LoadImages()
{
List<BitmapImage> robotImages = new List<BitmapImage>();
DirectoryInfo robotImageDir = new DirectoryInfo(@"..\folder");
foreach (FileInfo robotImageFile in robotImageDir.GetFiles("*.jpeg"))
{
Uri uri = new Uri(robotImageFile.FullName);
robotImages.Add(new BitmapImage(uri));
}
return robotImages;
}
}
XAML:
<Window.Resources>
<Style TargetType="{x:Type ListBox}">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border
Margin="6"
BorderBrush="Black" BorderThickness="4" CornerRadius="5"
>
<Image
Width="100" Height="120"
Source="{Binding Path=UriSource}" Stretch="Fill"
/>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Window.DataContext>
<ObjectDataProvider MethodName="LoadImages" ObjectType="{x:Type local:ImageLoader}" />
</Window.DataContext>
<ListBox x:Name="listBox" ItemsSource="{Binding}" />
答案 2 :(得分:0)
您应该实现MVVM模式并使用提供图像(路径)列表的属性创建视图模型,而不是使用静态LoadImages方法:
public class ViewModel
{
public ObservableCollection<string> ImagePaths { get; private set; }
= new ObservableCollection<string>();
public void LoadImagePaths(string path)
{
var dir = new DirectoryInfo(path);
foreach (FileInfo file in dir.EnumerateFiles("*.jpg"))
{
ImagePaths.Add(file.FullName);
}
}
}
在MainWindow或UserControl的构造函数中,您将创建该视图模型的实例,将其分配给DataContext
并调用其LoadImagePaths
方法:
public MainWindow()
{
InitializeComponent();
var vm = new ViewModel();
DataContext = vm;
vm.LoadImagePaths(@"C:\Users\Public\Pictures\Sample Pictures");
}
您的XAML如下所示。请注意,Source="{Binding}"
直接将Image.Source
属性绑定到路径字符串,然后自动将其转换为ImageSource
类型。
<ListBox ItemsSource="{Binding ImagePaths}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border>
<Image Source="{Binding}"/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>