evan
evan

Reputation: 21

Bind a collection to a WPF ListBox

Update: I've updated the code based on your help so far, and still no luck. When the application loads the ListBox has no items. I assign junk values to Customers in the windows's contructor, and then am also trying to set the ListBox's DataContext as follows:

CustomerList.DataContext = Customers;

--- Original Question (with updated code) ---

I'm having trouble with databinding in a WPF project.

I have a class, Customer, as follows:

public class Customer
{
    public String Name { get; set; }    
    public String Email { get; set; }
}

In my XAML's code behind I have a collection of customers as follows:

public List<Customer> Customers { get; set; }

I'm trying to bind each customer to a ListBox with a ListItemTemplate displaying the customer's information (name/email) in TextBoxes along with a button which locks/unloacks the TextBoxes (sets the IsEnabled property to true or false).

What's the best way to go about this?

So far I've been tryingt he following with no success.

In the XAML I currently have the following (ignoring the toggle part for now, I'm just trying to get the collection itself to be listed.):

<Window.Resources>
    <CollectionViewSource x:Key="Customers" Source="{Binding Path=Customers, Mode=TwoWay}"/>
    <DataTemplate x:Key="Customer">
        <StackPanel Orientation="Horizontal">
            <TextBox Content="{Binding Name}" />
            <TextBox Content="{Binding Email}" />
        </StackPanel>
    </DataTemplate>
</Window.Resources>

<StackPanel>
    <ListBox ItemsSource="{Binding Source={StaticResource Customers}}"
             ItemTemplate="{StaticResource ResourceKey=Customer}"
             Name="CustomerList"
             Height="300" />
</StackPanel>

Upvotes: 2

Views: 9594

Answers (3)

user1851476
user1851476

Reputation: 31

Code similar to the updated one works for me after changing

<TextBox Content="{Binding Name}" />

to

<TextBox Text="{Binding Name}" />

As TextBox doesn't have Content property(like a Label), the former refused to compile in VS.

Well, it is set to Text in definition:

[ContentPropertyAttribute("Text")]
public class TextBox : TextBoxBase, IAddChild

But I thought it is only used between the brackets(<TextBox>Like so</TextBox>)?

Could this be the source of the problem?

Upvotes: 1

AbdouMoumen
AbdouMoumen

Reputation: 3854

Try setting the ItemsSource of your CustomerList as follows: ItemsSource="{Binding}". You've set the DataContext of the ListBox to the list of customers, you need to set the ItemsSource to the same collection, hence, the direct binding.

Another thing that you can do, in case you prefer to use the CollectionViewSource, is to set the DataContext of your window to the same class DataContext=this, because without this, the resource definition won't be able to locate the "Customers" collection that you defined in the code behind. If you do this, however, you don't need CustomerList.DataContext = Customers; because you're directly assigning the ItemsSource to a static resource, not relatively to the DataContext.

One more thing. I think you should give the CollectionViewSource and the corresponding collection in the code behind different names. This isn't going to cause a runtime issue, but it makes it hard to maintain the code ;)

Hope this helps :)

Upvotes: 0

Matt Ellen
Matt Ellen

Reputation: 11612

You need to change

ItemsSource="{Binding Source=Customers}"

to

ItemsSource="{Binding Source={StaticResource Customers}}" DataContext="{StaticResource Customers}"

Upvotes: 1

Related Questions