mihajlv
mihajlv

Reputation: 2315

ObservableCollection doesn't get bound to ListBox in codebehind

I would like to bind a list box to an observable collection in code behind. This is what I am using for the binding:

Binding binding = new Binding();
binding.Source = symTable;
substanceList.SetBinding(ListBox.ItemsSourceProperty, binding);

symTable inherits from ObservableCollection, the Count property gets updated appropriatelly so I know I am adding elements correctly, but the list box isn't. I didn't know what to set the path to, since in XAML it is bound to the whole list.

Note: When adding individual items to the ListBox they get shown, so it is not a display issue. I also tried:

this.Resources.Add("symTable", symTable);

in the window constructor and then this:

but it says the resource cannot be resolved.

I also tried adding it as a resource in XAML but it didn't work again: //in the window's resources.

<s:SymbolTable x:Key="symTable"/> 
...
<ListBox x:Name="substanceList" ItemsSource="{Binding Source={StaticResource symTable}}"/>

and then in code behind:

symTable = (SymbolTable)this.FindResource("symTable");

Does anyone know any other way to do this in code behind or XAML, I think the ElementName refers to objects defined in code behind.

Here is part of the class definition for symTable:

public class SymbolTable : ObservableCollection<Substance>
{
    Dictionary<string, Substance> symbolTable;
    ...
    public Substance Insert(Substance s)
    {

        if (!symbolTable.ContainsKey(s.Name))
        {
            symbolTable.Add(s.Name, s);
            Items.Add(s);
        }

        return symbolTable[s.Name];
    }

Note alright so I just noticed the most weird thing, Items.Add wasn't raising the INotifyChanged event. I used Items.Add in my Insert method, I am guessing that Items.Add doesn't raise a INotifyChanged event so the ListBox wasn't getting updated, but when did Add instead of Items.Add then it worked. Do you know if this is indeed the case?

Upvotes: 0

Views: 455

Answers (3)

Clemens
Clemens

Reputation: 128146

Ok, following the comments on your question, here is how to declare SymbolTable as resource in XAML and how to bind a ListBox to it. Note the XAML namespace declaration 'local', which refers to the local namespace/assembly, which is named ListBindingTest in my test project.

<Window x:Class="ListBindingTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ListBindingTest"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:SymbolTable x:Key="symTable"/>
    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding Source={StaticResource symTable}}"/>
    </Grid>
</Window>

You may access the SymbolTable resource in code behind in your window class like this:

SymbolTable st = (SymbolTable)Resources["symTable"];
st.Add(new Substance());

Upvotes: 1

mdm20
mdm20

Reputation: 4563

You could always just set the ItemSource directly on the listbox.

substanceList.ItemsSource = symTable;

Upvotes: 0

paparazzo
paparazzo

Reputation: 45106

The DisplayMemberPath needs to be a public property of symTable.

Upvotes: 0

Related Questions