Attached Properties是您想要的一種方法。我經常使用它們。
附加屬性代碼:
Public Class TextBoxFormatter
' ------------------------------------------------------
' Define the FormatType attached property
Public Shared ReadOnly FormatTypeProperty As DependencyProperty = _
DependencyProperty.RegisterAttached(_
name:="FormatType", _
propertyType:=GetType(TextBoxFormatterType), _
ownerType:=GetType(TextBoxFormatter), _
defaultMetadata:=New FrameworkPropertyMetadata(_
defaultValue:=TextBoxFormatterType.None, _
PropertyChangedCallback:=New PropertyChangedCallback(AddressOf FormatTypePropertyChanged) _
) _
)
' ------------------------------------------------------
' Define the "getter" and "setter" for FormatType
Public Shared Function GetFormatType(ByVal target As DependencyObject) As TextBoxFormatterType
target.GetValue(FormatTypeProperty)
End Function
Public Shared Sub SetFormatType(ByVal target As DependencyObject, ByVal value As TextBoxFormatterType)
target.SetValue(FormatTypeProperty, value)
End Sub
' ------------------------------------------------------
' Define the FormatType "PropertyChanged" event handler
Private Shared Sub FormatTypePropertyChanged(ByVal target As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
If CType(e.NewValue, TextBoxFormatterType) = TextBoxFormatterType.None Then
UnregisterFormatTypeControl(target)
Else
RegisterFormatTypeControl(target)
End If
End Sub
' ------------------------------------------------------
' Define the a collection of event listerns for the
' FormatType "PropertyChanged" event
Private Shared _registeredFormatTypeControlDelegates As New Dictionary(Of TextBox, RoutedEventHandler)
' ------------------------------------------------------
' Register a control as an event listener
' (also, attach to the control's LostFocus event)
Private Shared Sub RegisterFormatTypeControl(ByVal candidate As DependencyObject)
Dim l_control = TryCast(candidate, TextBox)
If l_control IsNot Nothing Then
Dim l_handler = New RoutedEventHandler(AddressOf FormatTypeControl_LostFocus)
_registeredFormatTypeControlDelegates.Add(l_control, l_handler)
l_control.AddHandler(TextBox.LostFocusEvent, l_handler)
End If
End Sub
' ------------------------------------------------------
' Unregister a control as an event listener
' (also, unattach from the control's LostFocus event)
Private Shared Sub UnregisterFormatTypeControl(ByVal candidate As DependencyObject)
Dim l_control = TryCast(candidate, TextBox)
If l_control IsNot Nothing AndAlso _registeredFormatTypeControlDelegates.ContainsKey(l_control) Then
Dim l_handler = _registeredFormatTypeControlDelegates(l_control)
l_control.RemoveHandler(TextBox.LostFocusEvent, l_handler)
_registeredFormatTypeControlDelegates.Remove(l_control)
End If
End Sub
' ------------------------------------------------------
' On the control's LostFocus event, apply the format
' (You could apply the format based on another event,
' just be careful if using the TextChanged event - it
' will fire whether the user has changed the text or
' your code has changed the text - could introduce an
' infinite loop)
Private Shared Sub FormatTypeControl_LostFocus(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim l_textBox = TryCast(e.Source, TextBox)
If l_textBox IsNot Nothing Then
Dim l_formatType = CType(l_textBox.GetValue(FormatTypeProperty), TextBoxFormatterType)
Select Case l_formatType
Case TextBoxFormatterType.SocialSecurityNumber
' Apply the format to the l_textBox
' (What do you want a social security number to look like?)
Case TextBoxFormatterType.ZipCode
' Apply the format to the l_textBox
' (What do you want a zip code to look like?)
Case TextBoxFormatterType.Etc
' Apply the format to the l_textBox
End Select
End If
End Sub
End Class
Public Enum TextBoxFormatterType
None
ZipCode
SocialSecurityNumber
Etc
End Enum
上面看起來有點雜亂,但一旦代碼被寫入(一次),你可以在你的UI一遍又一遍用它:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:this="clr-namespace:WpfApplication1"
Title="Window1">
<Grid>
<StackPanel>
<TextBox this:TextBoxFormatter.FormatType="SocialSecurityNumber" />
<TextBox this:TextBoxFormatter.FormatType="ZipCode" />
<TextBox this:TextBoxFormatter.FormatType="None" />
</StackPanel>
</Grid>
</Window>
這種方法的一個優點是「FormatType」成爲一個依賴屬性,這意味着您可以在運行時將值綁定到它(而不僅僅是像上面的示例那樣進行編碼)。例如:
<TextBox this:TextBoxFormatter.FormatType="{Binding ViewModel.DesiredFormat}" />
來源
2012-06-04 17:09:01
JDB
您想對多個TextBox項使用通用代碼,以便它們的行爲相同嗎?在這種情況下,你很可能繼承TextBox的子類,然後使用這個自定義類。例如,如果它是電話號碼的TextBox,則可以將其命名爲「PhoneNumberTextBox」。 –
LostFocus不是DependencyProperty,它是一個事件,所以你不能將值綁定到它。當XAML解析器讀取LostFocus的XAML屬性中的文本時,它將使用反射來查找基類中具有相同名稱的方法。據我所知,沒有辦法來覆蓋這種行爲,也不會這樣做。您最好的選擇是使用下面介紹的解決方案之一。 – JDB