I'm trying to create custom RoutedEvent
in order to trigger an animation whenever the Text
property of a TextBlock
changes. My class inherits from TextBlock
class and I shadow the Text
property. I'm using a Button
in order to change the Text
property in some other value. My code does not produce any errors but it doesn't do anything. I'm sure that the problem is with the TextChanged
event because when I replace it with let's say MouseEnter
event, everything works ok.
Public Class MyCustomTextBlock
Inherits TextBlock
Public Shared ReadOnly TextChangedEvent As RoutedEvent = EventManager.RegisterRoutedEvent("TextChanged", _
RoutingStrategy.Bubble, GetType(RoutedEventArgs), GetType(MyCustomTextBlock))
Public Custom Event TextChanged As RoutedEventHandler
AddHandler(ByVal value As RoutedEventHandler)
Me.AddHandler(TextChangedEvent, value)
End AddHandler
RemoveHandler(ByVal value As RoutedEventHandler)
Me.RemoveHandler(TextChangedEvent, value)
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs)
Me.RaiseEvent(e)
End RaiseEvent
End Event
Public Shared Shadows TextProperty As DependencyProperty =
DependencyProperty.Register("Text", GetType(String), GetType(MyCustomTextBlock),
New FrameworkPropertyMetadata(String.Empty,
New PropertyChangedCallback(AddressOf TextPropertyChanged)))
Private Shared Sub TextPropertyChanged(ByVal sender As Object, ByVal e As DependencyPropertyChangedEventArgs)
DirectCast(sender, MyCustomTextBlock).RaiseEvent(New RoutedEventArgs(MyCustomTextBlock.TextChangedEvent))
End Sub
End Class
XAML
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="local:MyCustomTextBlock">
<Style.Triggers>
<EventTrigger RoutedEvent="local:MyCustomTextBlock.TextChanged">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="FontSize" To="30" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<local:MyCustomTextBlock x:Name="Textblock1" Text="xxxxxxxxx" Background="Yellow" Width="100" Height="25" />
<Button Content="Change Text" Height="23" HorizontalAlignment="Left" Margin="217,218,0,0" Name="Button1" VerticalAlignment="Top" Width="75" />
</Grid>
Class Main Window
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.Windows.RoutedEventArgs) Handles Button1.Click
Textblock1.Text = "apollon"
End Sub
End Class
It looks like the problem is that you're creating new members that conflict with those on the base TextBox
. You should consider using the TextChanged
event that already exists on TextBox
, or if you do need your own, name it something different. Here so far you aren't doing anything that the base properties don't do for you already.
The main issue with your specific question though appears to be with the new TextProperty
that you created. You shouldn't hide a dependency property on a base class, primarily because you can't control which one will be used in every situation, but also because there are mechanisms built in to make it unnecessary. In your case you've aggravated the problem by not fully implementing the boilerplate code for a DP. Because you have no wrapper property, your setting of the Text property from code is setting TextBox.Text
, which internally is calling SetValue
with TextBox.TextProperty
, hence skipping your code entirely.
Instead of declaring your own TextProperty
you can just tack on your metadata to the existing one. To add a change handler to the existing property add this call into a static constructor:
TextProperty.OverrideMetadata(GetType(MyCustomTextBlock),
New FrameworkPropertyMetadata(String.Empty,
New PropertyChangedCallback(AddressOf TextPropertyChanged)))