Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with binding a static ObservableCollection

I have a class (very little code for testing purposes) which contains a static ObservableCollection, which gets populated from elsewhere:

public class TestClass
{
    public static ObservableCollection<int> TestCollection = new ObservableCollection<int>();
}

... and a basic WPF window with a ListBox:

<Window x:Class="app.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListBox x:Name="list"/>
    </Grid>
</Window>

When I tried binding programmatically:

list.ItemsSource = Containers.TestClass.TestCollection;

... it worked just fine. However, when I try to perform binding through XAML:

<Window x:Class="app.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="clr-namespace:app.Containers"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <d:TestClass x:Key="dataSource"/>
    </Window.Resources>
    <Grid>
        <ListBox x:Name="list" ItemsSource="{Binding Source={StaticResource dataSource}, Path=TestCollection}"/>
    </Grid>
</Window>

... nothing gets displayed.

I've also tried setting DataContext:

<Window.Resources>
    <l:LifeEngine x:Key="dataSource"/>
</Window.Resources>
<Window.DataContext>
    <Binding Source="{StaticResource dataSource}"/>
</Window.DataContext>

...and using path...

...and nothing gets displayed once again.

Also, not sure if it matters, but when I make my class static I get an error in my XAML code saying:

The type 'TestClass' is abstract and must include an explicit value.

So, that's out of the question.

Any idea how I can bind that ObservableCollection through XAML?

like image 453
B.K. Avatar asked Jan 11 '23 00:01

B.K.


1 Answers

Problem is you are trying to find static property on an instance object.

<ListBox ItemsSource="{Binding Source={StaticResource dataSource},
                               Path=TestCollection}"/>

Here dataSource is pointing to an instance of TestClass and by binding Path to TestCollection, you are asking to bind to an instance property TestCollection which is static instead. That's why it's not working.

You have to use x:Static markup extension to bind to static properties. (Note you are not creating any instance object of TestClass)

<ListBox ItemsSource="{Binding Source={x:Static d:TestClass.TestCollection}}"/>

Also be informed that static properties binds one time. If you change the instance at runtime that won't be reflected back on UI. In your case you are dealing with ObservableCollection so when you add/delete item from collection it will be refreshed on UI but in case you reinitialize the list that change won't be reflected back on UI. In case you want to update UI, you have to raise StaticPropertyChangedEvent. In case interested, check out my answer here.

like image 101
Rohit Vats Avatar answered Jan 22 '23 14:01

Rohit Vats