I’ve encountered a problem when converting a WPF project from vs2008 to vs2010.
I have a DataGrid that contains a ListBox. Each ListBoxItem has a Label and a Button. After converting to vs2010 the button no longer renders but crashes the app as soon as it comes into view. (Ie. the app loads but when the ListBox is created I get a NullReferenceException. What does work though is to remove the click event from the button and then it renders fine 🙂 Same type of setup with Button within ListBoxItem also works when not inside a DataGrid. The content of ListBox obviously is meant to be dynamic but when working with a static collection I get the same error. Also removing the CommandParam does not help at all. Any pointers most welcome.
Code:
<DataGrid x:Name="DgTest" AutoGenerateColumns="false">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<ListBox ItemsSource="{Binding ItemList}">
<ListBox.ItemTemplate>
<DataTemplate >
<StackPanel Style="{StaticResource hzp}">
<Label />
<Button Click="Button_Click" Content="TestButton"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Code-behind:
Imports System.Collections.ObjectModel
Class MainWindow
Public TestList As New ObservableCollection(Of TestClass)
Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
DgTest.ItemsSource = TestList
TestList.Add(New TestClass(0))
TestList.Add(New TestClass(1))
End Sub
Public Class TestClass
Private _ItemList As New List(Of String)
Private _id As Integer
Public Property ItemList() As List(Of String)
Get
Return _ItemList
End Get
Set(ByVal value As List(Of String))
_ItemList = value
End Set
End Property
Public Property Id() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
Public Sub New(ByVal id As Integer)
_ItemList.Add("String1")
_id = id
End Sub
End Class
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
End Sub
End Class
And in App Resources:
<Style TargetType="StackPanel" x:Key="hzp">
<Setter Property="Orientation" Value="Horizontal"/>
<Setter Property="Background" Value="Orange"/>
</Style>
Now here’s the strange thing. If the Stackpanel Style is removed, the button will work. If the Click event for the button is removed, it will load normally.
I believe I have found the answer to my own question. In the ListBox bound to an ObservableCollection all Styles must be DynamicResource. Using StaticResource worked well in 3.5 but not 4! Took a few hours of randomly testing everything to find this. Case closed