I see a lot of questions in StackOverflow about writing two-way dependency properties. That's a dependency property that can update the bound property as well as reading it. Here's an example of a TextBox that implements an IsDirty dependency property. When the text box is dirty it sets the IsDirty dependency property true and turns the background light yellow. The hosting window can read or write the TextBox's IsDirty property.
Start a new Visual Studio WPF (Framework) application using Visual Basic and call it TwoWayDependencyProperty. The first thing we need to do is write our new TextBox control. Add a class and call it IsDirtyTextBox. It will inherit TextBox.
Inherits TextBox
Dim istb As IsDirtyTextBox = DirectCast(d, IsDirtyTextBox)
Public Property IsDirty As Boolean
Get
Return Convert.ToBoolean(GetValue(IsDirtyProperty))
End Get
Set(value As Boolean)
SetCurrentValue(IsDirtyProperty, value)
End Set
End Property
Dim bBackground As New Binding("IsDirty")
bBackground.Source = Me
bBackground.Converter = New IsDirtyConverter()
bBackground.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
Me.SetBinding(TextBox.BackgroundProperty, bBackground)
AddHandler Me.TextChanged, AddressOf Text_Changed
End Sub
Private Sub Text_Changed(sender As Object, e As TextChangedEventArgs)
IsDirty = True
End Sub
Implements IValueConverter
Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
Dim IsDirty As Boolean = System.Convert.ToBoolean(value)
If IsDirty Then
Return New SolidColorBrush(Colors.LightGoldenrodYellow)
Else
Return New SolidColorBrush(Colors.Transparent)
End If
End Function
Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
Throw New NotImplementedException()
End Function
End Class
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TwoWayDependencyProperty"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<StackPanel Orientation="Horizontal" Height="20">
<local:IsDirtyTextBox Width="100" Height="20" IsDirty="{Binding IsDirty, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="Is Dirty" Margin="10,0,0,0"/>
<CheckBox IsChecked="{Binding IsDirty, Mode=TwoWay}"/>
</StackPanel>
</Window>
Imports System.ComponentModel
Class MainWindow
Implements INotifyPropertyChanged
Private _IsDirty As Boolean
Public Property IsDirty As Boolean
Get
Return _IsDirty
Set(value As Boolean)
End Set
End Property
Public Event PropertyChanged As System.ComponentModel.PropertyChangedEventHandler Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Public Function SetProperty(Of T)(ByRef storage As T, value As T, <System.Runtime.CompilerServices.CallerMemberName> Optional PropertyName As String = Nothing) As Boolean
If Object.Equals(storage, value) Then Return False
storage = value
NotifyPropertyChanged(PropertyName)
Return True
End Function
Public Sub NotifyPropertyChanged(<System.Runtime.CompilerServices.CallerMemberName> Optional PropertyName As String = Nothing)
PropertyName = PropertyName.Substring(4)
End If
RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(PropertyName))
End Class
Here's the initial screen |
After changing text. Note the background and IsDirty property have changed |
After clearing the checkbox, background color has changed too |
You can see that the binding between the IsDirtyTextBox's IsDirty dependency property and the IsDirty property in the hosting window goes both ways. The TextBox can tell the window that it is dirty and the window can tell the TextBox not the be dirty.
No comments:
Post a Comment