2012-03-14 2 views
1

데이터베이스의 데이터를 표시하는 바운드 DataGrid에서 작업 중입니다. 그게 도움이된다면 Silverlight 5를 사용하고 있습니다. 현재 모든 데이터는 내 개체 개체 내의 Dictionary에 저장됩니다. 바인딩 경로에 Property[Key] 구문을 사용하면 표시 목적으로 올바르게 바인딩됩니다. 그러나 열은 런타임시 열 값을 변경하려고 할 때 읽기 전용처럼 작동합니다. DataGrid 열을 사전 항목에 양방향으로 바인딩 할 수 있습니까?

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) 

는 또한 의도 한대로 또한 작동하는 List,에 Property[Index] 경로 구문을 시도했다. 그래서 나는 왜 내가 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

정말 대답이 없지만 IValueConverter 메서드를 사용하여 양방향 바인딩을 원한다면 사전에 다시 키 데이터를 업데이트하기 위해 ConvertBack()을 구현해야합니다. . – allonym

+0

ConvertBack()을 구현하려고했지만 함수가 호출되지 않습니다. 셀이 절대로 ConvertBack()을 요구하는 편집 상태가되지 않기 때문에 결코 호출되지 않는다고 가정해야합니다. –

답변

0

나는 내 자신의 질문에 답하고 있지만, 다른 사람들에게이 문제가 도움이되기를 바랍니다.

정렬 된 목록을 사용하여 내 문제를 해결하기 위해 바운드 속성이 String 일 때 DataGridTextColumn 만 편집 할 수 있음을 발견했습니다. 예제의 사전이 Dictionary(Of String, String)으로 변경되면 셀의 양방향 바인딩과 편집이 의도 한대로 작동합니다. 또한 Object 만 반환하기 때문에 IValueConverter이 작동하지 않는 이유를 설명 할 수 있습니다. 문자열 대신 객체를 다루기를 원하므로 DataGridColumn의 간단한 요약을 만들었습니다. 내가 가진 한이 열 클래스가 DataGridTextColumn에 대한 교체로 사용됩니다

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 

, 모든 문제는 이제 사라졌다. 심지어 IValueConverter을 사용할 때 ConvertBack 함수가 호출됩니다.

관련 문제