Setting ListBox ItemsSource to an object from StaticResource as shown in MSDN

I was exploring DataTemplate and found Styling and Templating on MSDN. It says -

"In this sample application, there is a ListBox control that is bound to a list of photos:

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

This ListBox currently looks like the following:"

//...some stuff about DataTemplate...//

In our sample application, each custom Photo object has a Source property of type string that specifies the file path of the image. Currently, the photo objects appear as file paths."

"For the photos to appear as images, you create a DataTemplate as a resource:"

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

OK, fair enough, so I declared the Photo class -

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

My XAML sense is not very good (it's bad actually). What I don't get here is the way ItemsSource of the ListBox is set. As far as my XAML goes, "MyPhotos" here have to be an x:Key to an IEnumerable object of Photo type, something like -

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

But I don't have any idea how the PhotoList class should look like in this case. So, what the Resource would actually look like that cause the ListBox to be populated with the Source strings of the photos?

FYI : Implementing things in my own way, my DataTemplate exploration got successful, and though this thing here was not my primary concern, I just want to know what I don't know. Can anyone shed some light?

EDIT in response to the Answer provided by H.B.:

The point of the question is to get the result, as shown in the image, before applying the DataTemplate and to get an idea of the Resource that make that happen.

If I make the PhotoList itself an IEnumerable, like -

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

and instantiate it within the Resource, then to what the ItemsSource actually gets bound? How it's gonna work? Sorry I didn't understand. I hope you'll elaborate a bit more on this.

So, I went for the DataSourceProvider option. But since the Data property has no setter, I tried the following -

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);
    }
}  

And definitely I'm doing something wrong. Because, now i get the Cannot create an instance of "PhotoList" error message while instantiating PhotoList within the Resource -

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

Please help me out here.

Answers


The PhotoList itself either has to be an IEnumerable of Photo objects, or it needs to provide one, this can be done by inheriting from DataSourceProvider and exposing the list that way.


Edit: Obviously if you just inherit from List<T> nothing will display unless you add items, when i said it should be an IEnumerable i meant an immediate implementation that actually enumerates strings right away. If you just want to create a list in XAML you may as well use x:Array.

Also here would be an example of using the 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);
    }
}

This will populate your list with the paths of PNG-files in the personal "Pictures" folder.

Also you will not get the DataTemplate-less appearance of the example if you use a class like Photo unless you override ToString to return the source URL because by default if there is no DataTemplate it will just display the full name of the class.


In any case you need Photo objects in your collection for the DataTemplate to apply properly. Also you usually do not have collections directly in XAML but some data object which is the DataContext of the Window/UserControl.


Need Your Help

How to use model attribute inside form tag in a jsp?

spring jsp

I have a jsp form which has model attribute called projectId, I want to use it inside form tag as follows.

MS Access set cascade-to-null constraint to existing table

sql ms-access relationship

Using a MS Acess 2007 database accessed by vb.net application

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.