场景
1,动态生成数据结构(类似DataTable,Column不是固定的)
2,动态绑定到Datagrid
扩展了Microsoft的一个例子,增加了可以绑定Image类型的数据
Public Class TestDatagrid
Private Property StringTable As StringTable
Private Sub TestDatagrid_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
StringTable = New StringTable()
ResetTable()
dg.ItemsSource = StringTable.Values
End Sub
Private Sub ResetTable()
'create sample table
Dim sampleTable As New StringTable()
sampleTable.ColumnNames.Add("name")
sampleTable.ColumnNames.Add("age")
sampleTable.ColumnNames.Add("gender")
sampleTable.ColumnNames.Add("sex")
'add sample rows
sampleTable.Add(0, New StringRow() From {{"name", "person1"}, {"age", 20}, {"gender", "male"}, {"sex", True}})
sampleTable.Add(1, New StringRow() From {{"name", "person2"}, {"age", 18}, {"gender", "female"}, {"sex", True}})
sampleTable.Add(2, New StringRow() From {{"name", "person3"}, {"age", 22}, {"gender", "male"}, {"sex", False}})
sampleTable.Add(3, New StringRow() From {{"name", "person4"}, {"age", 17}, {"gender", "female"}, {"sex", True}})
Me.StringTable = sampleTable
RefreshDataGrid()
End Sub
Private Sub AdjustAllRowValues()
'make sure all rows contain values for all columns
For Each rowIndex As Integer In Me.StringTable.Keys
Dim row As StringRow = Me.StringTable(rowIndex)
If row.Count < Me.StringTable.ColumnNames.Count Then
For columnIndex As Integer = row.Count To Me.StringTable.ColumnNames.Count - 1
Dim cellValue As String = "r" & rowIndex & "c" & columnIndex
row.Add(Me.StringTable.ColumnNames(columnIndex), cellValue)
Next
End If
Next
End Sub
Private Sub RefreshDataGrid()
AdjustAllRowValues()
Me.DataGridContainer.Children.Clear()
Me.DataGridContainer.Children.Add(CreateDataGrid(Me.StringTable))
End Sub
Private Function CreateDataGrid(table As StringTable) As DataGrid
Dim dataGrid As New DataGrid()
dataGrid.ItemsSource = table.Values
dataGrid.AutoGenerateColumns = False
dataGrid.IsReadOnly = True
dataGrid.Columns.Clear()
For Each columnName As String In table.ColumnNames
If columnName.ToLower = "not text column" Then
Dim col1 As New DataGridTemplateColumn()
col1.Header = columnName
Dim factory1 As New FrameworkElementFactory(GetType(Image))
Dim b1 As New Binding
b1.Converter = New ColumnValueSelector()
b1.ConverterParameter = columnName
factory1.SetValue(Image.SourceProperty, b1)
Dim celltemplate1 As New DataTemplate()
celltemplate1.VisualTree = factory1
col1.CellTemplate = celltemplate1
dataGrid.Columns.Add(col1)
Else
Dim textColumn As New DataGridTextColumn()
textColumn.Header = columnName
Dim textConverter = New Binding
textConverter.Converter = New ColumnValueSelector()
textConverter.ConverterParameter = columnName
textColumn.Binding = textConverter
dataGrid.Columns.Add(textColumn)
End If
Next
Return (dataGrid)
End Function
End Class
Public Class ColumnValueSelector
Implements IValueConverter
Public Function Convert(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
Dim row As StringRow = DirectCast(value, StringRow)
Dim columnName As String = DirectCast(parameter, String)
Return (row(columnName))
End Function
Public Function ConvertBack(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
Throw New NotImplementedException()
End Function
End Class
Public Class StringRow
Inherits StringRow(Of String)
End Class
Public Class StringRow(Of T)
Inherits Dictionary(Of String, T)
End Class
Public Class StringTable
Inherits Dictionary(Of Integer, StringRow)
Public Property ColumnNames() As List(Of String)
Public Sub New()
ColumnNames = New List(Of String)()
End Sub
End Class