Yesterday I played around with WPF resources and stumbled on a very strange behavior, Check out this code
1: <Window.Resources>
2:Â
3: <Style TargetType=”ListBox”>
4: <Setter                   Property=”HorizontalAlignment” Value=”Center” />
5: </Style>
6:Â
7: <x:Array x:Key=”List” Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Type=”{x:Type sys:String}”>
8: <sys:String>A</sys:String>
9: <sys:String>B</sys:String>
10: <sys:String>C</sys:String>
11: <sys:String>D</sys:String>
12: <sys:String>E</sys:String>
13: </x:Array>
14:Â
15: </Window.Resources>
16:Â
17: <StackPanel>
18: <ListBox x:Name=”LstBox”
19: ItemsSource=”{Binding Source={StaticResource List}}”>
20: </ListBox>
21: </StackPanel>
Nothing our of the ordinary, an array, a Listbox binded to that array and and a style for the Listbox. Now starts the fun, if you compile and run this code you get nothing, the ListBox is empty!
The little thing in the red circle is the ListBox :). I kept on playing with it to check what is the problem and finally I got the following code which solved the problem:
1: <Window.Resources>
2:Â
3: <x:Array x:Key=”List” Type=”{x:Type sys:String}”>
4: <sys:String>A</sys:String>
5: <sys:String>B</sys:String>
6: <sys:String>C</sys:String>
7: <sys:String>D</sys:String>
8: <sys:String>E</sys:String>
9: </x:Array>
10:Â
11: <Style TargetType=”ListBox”>
12: <Setter Property=”HorizontalAlignment” Value=”Center” />
13: </Style>
14:
15: </Window.Resources>
16:Â
17: <StackPanel>
18: <ListBox x:Name=”LstBox”
19: ItemsSource=”{Binding Source={StaticResource List}}”>
20: </ListBox>
21: </StackPanel>
Can you see the difference? It’s subtle…
I just changed the position of the Style and the Array and magically it worked! How about that? now the window looks like this:
Things just got personal! I have decided to play around a bit more by adding another Listbox and another array placed after the style:
1: <Window.Resources>
2:Â
3: <x:Array x:Key=”List” Type=”{x:Type sys:String}”>
4: <sys:String>A</sys:String>
5: <sys:String>B</sys:String>
6: <sys:String>C</sys:String>
7: <sys:String>D</sys:String>
8: <sys:String>E</sys:String>
9: </x:Array>
10:Â
11: <Style TargetType=”ListBox”>
12: <Setter Property=”HorizontalAlignment” Value=”Center” />
13: </Style>
14:
15: <x:Array x:Key=”List2″ Type=”{x:Type sys:String}”>
16: <sys:String>A</sys:String>
17: <sys:String>B</sys:String>
18: <sys:String>C</sys:String>
19: <sys:String>D</sys:String>
20: <sys:String>E</sys:String>
21: </x:Array>
22:
23: </Window.Resources>
24:Â
25: <StackPanel>
26: <ListBox x:Name=”LstBox”
27: ItemsSource=”{Binding Source={StaticResource List}}”>
28: </ListBox>
29: <ListBox x:Name=”LstBox2″
30: ItemsSource=”{Binding Source={StaticResource List2}}”>
31: </ListBox>
32: </StackPanel>
What do you think was the result? Well surprise, surprise everything is OK:
I kept on going and moved both the Arrays after the Style and again nothing showed up. For the final test I tried changing the binding expression on one of the first Listbox to be more explicit so it looked like this:
1: <ListBox x:Name=”LstBox”
2: ItemsSource=”{Binding Path=Items,Source={StaticResource List}}”>
3: </ListBox>
And there you go! The items appeared in the Listbox
The little dot at the bottom is the second ListBox.
Conclusion: Use Explicit Binding, it seems to be safer, or put static data in from of all the style in the resources (I have no idea why that works)
If anyone knows why putting the array in first works please comment
Amit.
By John Oxley on Apr 21, 2008 | Reply
It’s not a bug in WPF. In C# when you declare static variables the order DOES matter. You cannot do this:
static int foo = bar * 2;
static in bar = 5;
Someone more intelligent than I will tell you why.
By Amit on Apr 21, 2008 | Reply
Hey John
I dont think it is the same as the array and the style are not related. the Listbox is using them both. If we would make the analogy i would say it is more like this (as far as i get it):
this would work:
static int foo = 2;
static in bar = 5;
int i = foo*bar;
where as this would not work
static int bar = 5;
static int foo = 2;
int i = foo*bar;
so it is still weird
Amit