WPF在列表框错误中显示图像

时间:2016-05-02 08:59:49

标签: c# wpf listbox

我想从文件夹向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中

3 个答案:

答案 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>