2014-06-17 84 views
0

單選按鈕的綁定到對象的單個屬性我有一個數據類定義如下(縮短爲了簡潔):WPF數據網格(雙向)中收集

Partial Public Class ClassName 
    Inherits ObservableCollection(Of MyObject) 

    Public Event ItemPropertyChanged As PropertyChangedEventHandler 

    Private Property _ContainsChanges As Boolean 
    Public ReadOnly Property ContainsChanges As Boolean 
     Get 
      Return _ContainsChanges 
     End Get 
    End Property 

    Protected Overridable Sub Notify_PropertyChanged(ByVal PropertyName As String) 
     MyBase.OnPropertyChanged(New PropertyChangedEventArgs(PropertyName)) 
    End Sub 

    Protected Overridable Sub Notify_ItemPropertyChanged(ByVal e As PropertyChangedEventArgs) 
     RaiseEvent ItemPropertyChanged(Me, e) 
    End Sub 

    Protected Overridable Sub Me_PropertyChanged(ByVal sender As Object, e As PropertyChangedEventArgs) Handles Me.PropertyChanged 
     Me._ContainsChanges = True 
    End Sub 

    Protected Overridable Sub Me_CollectionChanged(Sender As Object, e As NotifyCollectionChangedEventArgs) Handles Me.CollectionChanged 
     If e.Action = NotifyCollectionChangedAction.Add Then 
      For Each item As Account In e.NewItems 
       AddHandler item.PropertyChanged, AddressOf Account_PropertyChanged 
      Next 
     ElseIf e.Action = NotifyCollectionChangedAction.Remove Then 
      For Each item As Account In e.OldItems 
       RemoveHandler item.PropertyChanged, AddressOf Account_PropertyChanged 
      Next 
     End If 
    End Sub 

    Protected Overridable Sub MyObject_PropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) 
     Me._ContainsChanges = True 
     Notify_ItemPropertyChanged(e) 
    End Sub 

    Partial Public Class MyObject 
     Implements INotifyPropertyChanged 

     Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged 

     Private Property _ContainsChanges As Boolean 
     Public ReadOnly Property ContainsChanges As Boolean 
      Get 
       Return _ContainsChanges 
      End Get 
     End Property 

     Private Property _IntegerProperty As Integer 
     Public Property IntegerProperty As Integer 
      Get 
       Return _IntegerProperty 
      End Get 
      Set(value As Integer) 
       If value <> _IntegerPropertyThen 
        _IntegerProperty= value 
        Notify_PropertyChanged("IntegerProperty") 
       End If 
      End Set 
     End Property 

     Private Property _BooleanProperty As Nullable(Of Boolean) 
     Public Property BooleanProperty As Nullable(Of Boolean) 
      Get 
       Return _BooleanProperty 
      End Get 
      Set(value As Boolean) 
       If value <> _BooleanProperty Then 
        _BooleanProperty = value 
        Notify_PropertyChanged("BooleanProperty ") 
       End If 
      End Set 
     End Property 

     Private Sub Notify_PropertyChanged(ByVal PropertyName As String) 
      RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName)) 
     End Sub 

     Protected Overridable Sub Me_PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Handles Me.PropertyChanged 
      Me._ContainsChanges = True 
     End Sub 
    End Class 
End Class 

這個集合被綁定到一個WPF用戶使用數據網格作爲其唯一元素進行控制。集合中的每個對象都由數據網格中的一行表示。該XAML如下所示:

<UserControl 
      x:Class="WPFControlNameSpace.WPFControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:converters="clr-namespace:WPFControlLibrary.WPFControlNameSpace.Converters" 
      DataContext="{Binding DataGrid}"> 
    <UserControl.Resources> 
     <converters:BooleanConverter x:Key="BooleanConverter"/> 
     <Style TargetType="{x:Type DataGridColumnHeader}" x:Key="dgHeaderStyle"> 
      <Setter Property="Background" Value="Beige" /> 
      <Setter Property="Height" Value="30" /> 
      <Setter Property="FontSize" Value="15" /> 
      <Setter Property="BorderBrush" Value="Black" /> 
      <Setter Property="FontWeight" Value="Bold" /> 
      <Setter Property="BorderThickness" Value=".5" /> 
      <Setter Property="HorizontalContentAlignment" Value="Center" /> 
      <Setter Property="FontFamily" Value="Arial" /> 
     </Style> 
     <Style TargetType="{x:Type DataGrid}" x:Key="dgStyle"> 
      <Setter Property="AlternatingRowBackground" Value="Beige" /> 
      <Setter Property="AutoGenerateColumns" Value="False" /> 
      <Setter Property="CanUserAddRows" Value="False" /> 
      <Setter Property="CanUserDeleteRows" Value="False" /> 
      <Setter Property="FontSize" Value="13" /> 
      <Setter Property="MinColumnWidth" Value="30" /> 
     </Style> 
    </UserControl.Resources> 
    <DataGrid x:Name="dgClassName" 
       ItemsSource="{Binding}" 
       ColumnHeaderStyle ="{StaticResource dgHeaderStyle}" 
       Style="{StaticResource dgStyle}" 
       RowDetailsVisibilityMode="Collapsed" 
       HeadersVisibility="Column" 
       FontFamily="Arial"> 
     <DataGrid.RowStyle> 
      <Style TargetType="DataGridRow"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding lActive}" Value="True"> 
         <Setter Property="ToolTip" Value="This row is Active!" /> 
        </DataTrigger> 
        <DataTrigger Binding="{Binding lActive}" Value="False"> 
         <Setter Property="ToolTip" Value="This row is Inactive!" /> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </DataGrid.RowStyle> 
     <DataGrid.CellStyle> 
      <Style TargetType="DataGridCell"> 
       <Style.Triggers> 
        <Trigger Property="IsSelected" Value="True"> 
         <Setter Property="Foreground" Value="Black" /> 
         <Setter Property="Background" Value="{x:Null}" /> 
         <Setter Property="BorderBrush" Value="{x:Null}" /> 
        </Trigger> 
       </Style.Triggers> 
      </Style> 
     </DataGrid.CellStyle> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header=" Account Number " Binding="{Binding nAccountNumber}" IsReadOnly="True" MinWidth="50"/> 
      <DataGridTextColumn Header=" Account Description " Binding="{Binding cAccountDescription}" IsReadOnly="True" MinWidth="50"/> 
      <DataGridTemplateColumn Header=" Verified "> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <StackPanel Grid.Row="1" Orientation="Horizontal"> 
          <RadioButton Content="Yes" 
             IsChecked="{Binding BooleanProperty, 
                Converter={StaticResource BooleanConverter}, 
                ConverterParameter='True', Mode=TwoWay}" /> 
          <RadioButton Content="No" 
             IsChecked="{Binding BooleanProperty, 
                Converter={StaticResource BooleanConverter}, 
                ConverterParameter='False', Mode=TwoWay}" /> 
          <RadioButton Content="Unknown" 
             IsChecked="{Binding BooleanProperty, 
                Converter={StaticResource BooleanConverter}, 
                ConverterParameter='Nothing', Mode=TwoWay}" /> 
         </StackPanel> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 

     </DataGrid.Columns> 
    </DataGrid> 
</UserControl> 

,我使用如下所示的轉換:

Namespace SungardVerification.Converters 
    Class BooleanConverter 
     Implements IValueConverter 
     Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.Convert 
      Dim SourceValue = CType(value, System.Nullable(Of Boolean)) 
      Dim RadioButtonCheckedValue As Nullable(Of Boolean) = Nothing 

      If DirectCast(parameter, String).ToUpper.Trim() <> "NOTHING" Then 
       RadioButtonCheckedValue = Boolean.Parse(DirectCast(parameter, String)) 
      End If 

      If (RadioButtonCheckedValue.HasValue AndAlso SourceValue.HasValue AndAlso RadioButtonCheckedValue.Value = SourceValue.Value) OrElse 
       (Not RadioButtonCheckedValue.HasValue AndAlso Not SourceValue.HasValue) Then 
       Return True 
      Else 
       Return False 
      End If 
     End Function 

     Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack 
      Dim RadioButtonChecked = CType(value, Boolean) 
      Dim RadioButtonCheckedValue As Nullable(Of Boolean) = Nothing 
      Dim SourceValue As Nullable(Of Boolean) = Nothing 

      If RadioButtonChecked = True Then 
       If DirectCast(parameter, String).ToUpper.Trim() <> "NOTHING" Then 
        SourceValue = Boolean.Parse(DirectCast(parameter, String)) 
       End If 
       Return SourceValue 
      Else 
       Return Binding.DoNothing 
      End If 
     End Function 
    End Class 
End Namespace 

該控制存在於一個用戶控件庫,並使用元素被包括在Windows窗體上主辦。

datagrid正確地將集合中的值綁定到單元格,但是此綁定的雙向方面無法正常工作。

我知道這可以用一個不確定的複選框來完成,但單選按鈕對於用戶選擇的含義會更清楚。

有沒有人有任何建議如何得到這個工作?

回答

0

由於UpdateSourceTrigger屬性保留爲默認值,因此未發現正確的行爲。將XAML更改爲下面的內容可解決我的問題。

<RadioButton Content="Unknown" 
      IsChecked="{Binding BooleanProperty, 
         Converter={StaticResource BooleanConverter}, 
         ConverterParameter='Nothing', Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />