将ListBox ItemsSource设置为StaticResource中的对象,如MSDN中所示

时间:2012-09-10 17:22:11

标签: c# wpf xaml itemssource staticresource

我正在探索DataTemplate并在MSDN上找到Styling and Templating。它说 -

在此示例应用程序中,有一个ListBox控件绑定到照片列表:

<ListBox ItemsSource="{Binding Source={StaticResource MyPhotos}}"
     Background="Silver" Width="600" Margin="10" SelectedIndex="0"/>  

此ListBox目前如下所示:

enter image description here

// ...关于DataTemplate ... //

的一些内容

在我们的示例应用程序中,每个自定义Photo对象都具有string类型的Source属性,该属性指定图像的文件路径。目前,照片对象显示为文件路径。

要使照片显示为图像,您需要将DataTemplate创建为资源:

<Window.Resources>
...
<!--DataTemplate to display Photos as images
    instead of text strings of Paths-->
<DataTemplate DataType="{x:Type local:Photo}">
  <Border Margin="3">
    <Image Source="{Binding Source}"/>
  </Border>
</DataTemplate>
...
</Window.Resources>  

好的,公平的,所以我宣布了Photo类 -

public class Photo
{
    public string Source { get; set; }
} 

我的XAML感觉不是很好(实际上它)。我没有得到的是ListBox的 ItemsSource 的设置方式。就我的XAML而言,这里的“MyPhotos”必须是照片类型的 IEnumerable 对象的x:Key,类似于 -

<Window.Resources>
...
<local:PhotoList x:Key="MyPhotos"/>
...
</Window.Resources>  

但我不知道 PhotoList 类在这种情况下应该是什么样子。那么, Resource 实际上会是什么导致ListBox被照片的Source字符串填充?

FYI:以我自己的方式实施事情,我的DataTemplate探索取得了成功,虽然这里的事情不是我主要考虑的问题,但我只是想知道我不知道的是什么知道。任何人都能解释一下吗?

编辑以回应 H.B.提供的答案

问题的关键是在应用DataTemplate之前获得结果,如图中所示,并了解实现这种情况的资源。

如果我将PhotoList本身设为 IEnumerable ,就像 -

public class PhotoList : List<Photo>
{
    //some property to hold the collection of Photo objects??
}

并在Resource中实例化它,然后 ItemsSource实际绑定了什么?怎么样?对不起,我不明白。我希望你能详细说明一下。

所以,我去了DataSourceProvider选项。但由于Data属性没有setter,我尝试了以下内容 -

public class Photo
{
    public string Source { get; set; }
}

public class PhotoList : DataSourceProvider
{
    private List<Photo> _photos;

    public PhotoList()
    {
        _photos = new List<Photo>
                      {
                          new Photo{ Source = @"D:\AppImage\1.jpg"},
                          new Photo{ Source = @"D:\AppImage\2.jpg"},
                          new Photo{ Source = @"D:\AppImage\3.jpg"},
                          new Photo{ Source = @"D:\AppImage\4.jpg"},
                          new Photo{ Source = @"D:\AppImage\5.jpg"},
                      };
        ((List<Photo>)this.Data).AddRange(_photos);
    }
}  

我肯定做错了什么。因为,现在我得到了在资源中实例化PhotoList时无法创建“PhotoList”错误消息的实例 -

<Window.Resources>
    <local:PhotoList x:Key="MyPhotos"/>
</Window.Resources>  

请帮帮我。

2 个答案:

答案 0 :(得分:1)

PhotoList本身必须是IEnumerablePhoto个对象,或者它需要提供一个,这可以通过继承DataSourceProvider并暴露这样列出。


修改 显然,如果你只是从List<T>继承,除非你添加项目,否则什么都不会显示,当我说它应该是IEnumerable时,我的意思是立即实现,它实际上会立即枚举字符串。如果您只想在XAML中创建列表,也可以使用x:Array

此处也是使用DataSourceProvider

的示例
public class PhotoList : DataSourceProvider
{
    protected override void BeginQuery()
    {
        var files = Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures))
                        .Where(f => Path.GetExtension(f) == ".png")
        OnQueryFinished(files);
    }
}

这将使用个人“图片”文件夹中的PNG文件路径填充您的列表。

如果您使用类似DataTemplate的类,除非您覆盖Photo以返回源URL,否则您将无法获得ToString - 更少的示例外观,因为默认情况下如果有没有DataTemplate它只会显示该类的全名。


在任何情况下,您的集合中都需要Photo个对象才能正确应用DataTemplate。此外,您通常不会直接在XAML中拥有集合,而是一些数据对象,即Window / UserControl的{​​{3}}。

答案 1 :(得分:0)

 <Window.Resources>
    <ph:PhotoList x:Key="MyPhotos"  Path="D:\Visual Studio Projects\WPF APPLICATIONS\ImageViewer\ImageViewer\Images">      
    </ph:PhotoList>    
 </Window.Resources>