views:

33

answers:

2

I don't know what I'm doing wrong here. I have a ListBox whose DataContext and ItemsSource are set, but there is nothing in the ListBox when I run my app. When debugging, the first line of my method for getting items for the ListBox never gets hit. Here's what I have:

// Constructor in UserControl
public TemplateList()
{
    _templates = new Templates();
    InitializeComponent();
    DataContext = this;
}

// ItemsSource of ListBox
public List<Template> GetTemplates()
{
    if (!tryReadTemplatesIfNecessary(ref _templates))
    {
        return new List<Template>
            {
                // Template with Name property set:
                new Template("No saved templates", null)
            };
    }
    return _templates.ToList();
}

Here's my XAML:

<ListBox ItemsSource="{Binding Path=GetTemplates}" Grid.Row="1" Grid.Column="1"
         Width="400" Height="300" DisplayMemberPath="Name"
         SelectedValuePath="Name"/>

On an instance of the Template class, there's a Name property that is just a string. All I want is to display a list of template names. The user won't change any data in a Template, the ListBox just needs to be read-only.

A Template also has a Data property that I will later display in this ListBox, so I don't want to make GetTemplates return just a list of strings--it needs to return some collection of Template objects.

+5  A: 

You can't bind to a method. Make it a property and it should work.

Its better though to set the List as DataContext, or create a ViewModel that holds the list. Thay way, you will have more control over the instances your Listbox will bind to.

Hope this helps!

Arcturus
This is much cleaner! I made my `GetTemplates` method private and set `DataContext = GetTemplates()` in the constructor. Then I just set `ItemsSource` in my XAML to the `List` property my `Templates` class already had--thanks!
Sarah Vessels
Glad I could help ;)
Arcturus
BTW if you really wish to call a method from Xaml, take a look at the ObjectDataProvider. Bea Stollnitz has a nice blog about it:http://bea.stollnitz.com/blog/?p=22
Arcturus
+1  A: 

You're attempting to call a method in your binding when you should be using a property. Change it to a property and you should be good to go.

public List<Template> MyTemplates {get; private set;}

public TemplateList()
{
    InitializeComponent();
    SetTemplates();
    DataContext = this;
}

// ItemsSource of ListBox
public void SetTemplates()
{
    // do stuff to set up the MyTemplates proeprty
    MyTemplates = something.ToList();
}

Xaml:

<ListBox ItemsSource="{Binding Path=MyTemplates}" Grid.Row="1" Grid.Column="1"
   Width="400" Height="300" DisplayMemberPath="Name"
   SelectedValuePath="Name"/>
Metro Smurf