我正在处理显示数据库数据的绑定DataGrid
。如果有帮助,我正在使用Silverlight 5。目前,所有数据都存储在我的实体对象中的Dictionary
中。使用绑定路径的Property[Key]
语法可以正确绑定以用于显示目的。但是,当尝试在运行时更改列值时,该列的行为就像是readonly一样。
Public Class Entity
Public Property Attributes As New Dictionary(Of String, Object)
End Class
'Sample data
Dim Entities As New List(Of Entity)
Entities.Add(New Entity With {.Attributes = New Dictionary(Of String, Object) From {{"Name", "Joe"}, {"City", "Detroit"}}})
Entities.Add(New Entity With {.Attributes = New Dictionary(Of String, Object) From {{"Name", "Bob"}, {"City", "Chicago"}}})
Entities.Add(New Entity With {.Attributes = New Dictionary(Of String, Object) From {{"Name", "Fred"}, {"City", "Dallas"}}})
MyDataGrid1.ItemsSource = Entities
<sdk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}" Margin="12,276,12,12" Name="MyDataGrid1">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding Path=Attributes[Name], Mode=TwoWay}" Header="Name" Width="Auto" />
<sdk:DataGridTextColumn Binding="{Binding Path=Attributes[City], Mode=TwoWay}" Header="City" Width="Auto" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
我尝试在单个实体上使用相同的绑定设置文本框,并且所有内容都按预期显示和设置值。这应排除Dictionary
作为问题。
<TextBox Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="TextBox1" VerticalAlignment="Top" Width="120" Text="{Binding Path=Attributes[Name], Mode=TwoWay}" />
TextBox1.DataContext = Entities(1)
我还在Property[Index]
上尝试了List
路径语法,该语法也按预期工作。所以我想我现在不明白为什么DataGrid
不允许我编辑列项。
我的另一个想法是为列使用值转换器并将密钥作为转换器参数传递。但DataGrid
的行为方式与仅绑定Property[Key]
的方式相同,不允许对该列进行编辑。
Public Class AttributeValueConverter
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 Attributes As Dictionary(Of String, Object) = value
Dim Name As String = parameter
If Attributes IsNot Nothing And Name IsNot Nothing Then
Return Attributes(Name)
End If
Return Nothing
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
<UserControl.Resources>
<ps:AttributeValueConverter x:Key="AttributeValueConverter"/>
</UserControl.Resources>
<sdk:DataGridTextColumn Binding="{Binding Path=Attributes, Mode=TwoWay, Converter={StaticResource AttributeValueConverter}, ConverterParameter=Name}" Header="Name" Width="Auto" />
有没有人遇到过这种情况或者对如何实现目标有任何建议?我现在唯一想到的是将列值存储在有序列表中,并使用索引而不是键来显示它们。但我真的很想知道为什么关键不起作用。
答案 0 :(得分:0)
我知道我正在回答我自己的问题,但我希望它可以帮助其他任何人解决这个问题。
在尝试使用有序列表解决我的问题时,我发现DataGridTextColumn
仅允许在绑定属性为String
时进行编辑。当我的示例中的词典更改为Dictionary(Of String, String)
时,单元格的双向绑定和编辑按预期工作。这也可以解释为什么IValueConverter
不起作用,因为它只会返回Object
。我仍然想处理对象而不是字符串,所以我快速摘录了DataGridColumn
。
Public Class MyDataGridTextColumn
Inherits DataGridColumn
Private _Binding As Binding
Public Property Binding As Binding
Get
Return Me._Binding
End Get
Set(ByVal value As Binding)
If Me._Binding IsNot value Then
Me._Binding = value
End If
End Set
End Property
Protected Overrides Function GenerateElement(cell As System.Windows.Controls.DataGridCell, dataItem As Object) As System.Windows.FrameworkElement
Dim textBlock As TextBlock = New TextBlock()
textBlock.Margin = New Thickness(4)
textBlock.VerticalAlignment = VerticalAlignment.Center
If Me.Binding IsNot Nothing Then
textBlock.SetBinding(textBlock.TextProperty, Me.Binding)
End If
Return textBlock
End Function
Protected Overrides Function GenerateEditingElement(cell As System.Windows.Controls.DataGridCell, dataItem As Object) As System.Windows.FrameworkElement
Dim textBox As TextBox = New TextBox()
textBox.VerticalAlignment = VerticalAlignment.Stretch
textBox.Background = New SolidColorBrush(Colors.Transparent)
If Me.Binding IsNot Nothing Then
textBox.SetBinding(textBox.TextProperty, Me.Binding)
End If
Return textBox
End Function
End Class
当此列类用作DataGridTextColumn
的替代时,我遇到的所有问题现在都消失了。使用ConvertBack
时,甚至会调用IValueConverter
函数。