I am in the process of evaluating VS 2013/Net 4.5. Most things (although the IDE behaves really poorly requiring double clicks of watches etc.) behave exactly the same. I was translating some attached properties that I have to 4.5 and ran into a real head scratcher.
I have an attached prop that when used allow the ListView to have an GenerateColumnsGridView property that will generate the columns from the ItemsSource. It works great in 4.0 but in 4.5 it totally falls apart.
The XAML to test the case is very simple:
<ListView x:Name="theListView1" ItemsSource="{Binding theList}" Grid.Row="2"
local:DynamicBindingListView.GenerateColumnsGridView="True"
local:DynamicBindingListView.DateFormatString="MM/dd/yyyy"><ListView.View><GridView></GridView></ListView.View></ListView>This is the code used in both VS2010 and VS2013.
In the attached property there is code to retrieve the view of the ListView when the ItemsSource is changed. In VS2010 there is a GridView in the View property of the Listview. In VS2013 the View property is null/nothing.
The Code Behind is (and it is the same for both versions of VS):
Imports System.ComponentModel
Imports System.Collections.Specialized
Imports System.Reflection
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Data
Public Class DynamicBindingListView
Public Shared Function GetDateFormatString(ByVal element As DependencyObject) As String
If element Is Nothing Then
Throw New ArgumentNullException("element")
End If
Return element.GetValue(DateFormatStringProperty)
End Function
Public Shared Sub SetDateFormatString(ByVal element As DependencyObject, ByVal value As String)
If element Is Nothing Then
Throw New ArgumentNullException("element")
End If
element.SetValue(DateFormatStringProperty, value)
End Sub
Public Shared ReadOnly DateFormatStringProperty As _
DependencyProperty = DependencyProperty.RegisterAttached("DateFormatString", _
GetType(String), GetType(DynamicBindingListView), _
New FrameworkPropertyMetadata(Nothing))
Public Shared Function GetGenerateColumnsGridView(ByVal element As DependencyObject) As Boolean
If element Is Nothing Then
Throw New ArgumentNullException("element")
End If
Return element.GetValue(GenerateColumnsGridViewProperty)
End Function
Public Shared Sub SetGenerateColumnsGridView(ByVal element As DependencyObject, ByVal value As Boolean)
If element Is Nothing Then
Throw New ArgumentNullException("element")
End If
element.SetValue(GenerateColumnsGridViewProperty, value)
End Sub
Public Shared ReadOnly GenerateColumnsGridViewProperty As _
DependencyProperty = DependencyProperty.RegisterAttached("GenerateColumnsGridView", _
GetType(Boolean?), GetType(DynamicBindingListView), _
New FrameworkPropertyMetadata(Nothing, AddressOf thePropChanged))
Public Shared Sub thePropChanged(ByVal obj As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
Try
Dim lv As ListView = CType(obj, ListView)
Dim descriptor As DependencyPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(ListView.ItemsSourceProperty, GetType(ListView))
descriptor.AddValueChanged(lv, New EventHandler(AddressOf ItemsSourceChanged))
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Shared Sub ItemsSourceChanged(sender As Object, e As EventArgs)
Try
Dim lv As ListView = CType(sender, ListView)
Dim its As IEnumerable = lv.ItemsSource
Dim itsEnumerator As IEnumerator = its.GetEnumerator
Dim hasItems As Boolean = itsEnumerator.MoveNext()
If hasItems Then
SetUpTheColumns(lv, itsEnumerator.Current)
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Shared Sub SetUpTheColumns(theListView As ListView, firstObject As Object)
Try
Dim theClassProperties As PropertyInfo() = firstObject.GetType().GetProperties()
Dim gv As GridView = theListView.View
For Each pi As PropertyInfo In theClassProperties
Dim columnName As String = pi.Name
Dim grv As New GridViewColumn With {.Header = columnName}
If pi.PropertyType Is GetType(DateTime) Then
Dim bnd As New Binding(columnName)
Dim formatString As String = theListView.GetValue(DateFormatStringProperty)
If formatString <> String.Empty Then
bnd.StringFormat = formatString
End If
BindingOperations.SetBinding(grv, TextBlock.TextProperty, bnd)
grv.DisplayMemberBinding = bnd
ElseIf isNumber(pi.PropertyType) Then
Dim bnd As New Binding(columnName)
BindingOperations.SetBinding(grv, TextBlock.TextProperty, bnd)
grv.DisplayMemberBinding = bnd
Else
Dim bnd As New Binding(columnName)
BindingOperations.SetBinding(grv, TextBlock.TextProperty, bnd)
grv.DisplayMemberBinding = bnd
End If
gv.Columns.Add(grv)
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Shared Function isNumber(intype As Type) As Boolean
Dim _isNumber As Boolean = False
Select Case intype.Name
Case "Integer", "Int32"
_isNumber = True
End Select
Return _isNumber
End Function
End Class
I guess the real question is whether dot.net 4.5 is ready for prime time and is VS 2013 going to be fixed such that all the IDE problems are sorted out.
If someone would be good enough to try the code in both VS 2010 and VS 2013 you will see that when the attached prop is actioned by an ItemsSource change the two are as far apart from behaving the same as possible.
TIA
Lloyd Sheen