我有一个数据类定义如下(为简洁起见缩短):
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用户控件,其中datagrid是其唯一元素。集合中的每个对象都由datagrid中的一行表示。 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 :(得分:0)
没有注意到正确的行为,因为UpdateSourceTrigger属性保留为默认值。将XAML更改为以下内容可以解决我的问题。
<RadioButton Content="Unknown"
IsChecked="{Binding BooleanProperty,
Converter={StaticResource BooleanConverter},
ConverterParameter='Nothing', Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />