How to detect a change in the Text property of a TextBlock?

后端 未结 6 1660
梦如初夏
梦如初夏 2020-12-09 16:55

Is there any way to detect a change in the Text property of a TextBlock element using events?

(I\'m trying to provide an animation for highlighting the TextBlocks wh

相关标签:
6条回答
  • 2020-12-09 17:09

    As far as I can understand there isn't any textchanged event in TextBlock. Looking at your requirement, I feel that re-templating a textbox will also not be a viable solution. From my preliminary searching around, this seems to be a possible solution.

    <TextBlock x:Name="tbMessage" Text="{Binding Path=StatusBarText, NotifyOnTargetUpdated=True}">
        <TextBlock.Triggers>
            <EventTrigger RoutedEvent="Binding.TargetUpdated">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:0″
    To="1.0″ />
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:2″
    From="1.0″ To="0.0″ BeginTime="0:0:5″ />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </TextBlock.Triggers>
    </TextBlock>
    
    0 讨论(0)
  • 2020-12-09 17:10

    Bind the Text property to a DependencyProperty, which has an event trigger:

    public static string GetTextBoxText(DependencyObject obj)
    {
        return (string)obj.GetValue(TextBoxTextProperty);
    }
    
    public static void SetTextBoxText(DependencyObject obj, string value)
    {
        obj.SetValue(TextBoxTextProperty, value);
    }
    
    public static readonly DependencyProperty TextBoxTextProperty =
        DependencyProperty.RegisterAttached(
        "TextBoxText",
        typeof(string),
        typeof(TextBlockToolTipBehavior),
        new FrameworkPropertyMetadata(string.Empty, TextBoxTextChangedCallback)
        );
    
    private static void TextBoxTextChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBlock textBlock = d as TextBlock;
        HandleTextChange(textBlock);
    }
    

    In the XAML Bind to the TextBlock text Property:

    <TextBlock  
     Text="{Binding SomeProperty, UpdateSourceTrigger=PropertyChanged}"  
         th:TextBlockBehavior.TextBoxText="{Binding Text, 
         RelativeSource={RelativeSource Self}}" />
    
    0 讨论(0)
  • 2020-12-09 17:16

    It's easier than that! Late answer, but much simpler.

    // assume textBlock is your TextBlock
    var dp = DependencyPropertyDescriptor.FromProperty(
                 TextBlock.TextProperty,
                 typeof(TextBlock));
    dp.AddValueChanged(textBlock, (sender, args) =>
    {
        MessageBox.Show("text changed");
    });
    
    0 讨论(0)
  • 2020-12-09 17:21

    Here is a similar example on MSDN using code-behind: http://msdn.microsoft.com/en-us/library/system.windows.data.binding.targetupdated.aspx

    0 讨论(0)
  • 2020-12-09 17:23

    This is like the code from the link in bioskope's answer, but simplified. You need the TargetUpdated event and add NotifyOnTargetUpdated=True to the binding.

    <TextBlock Text="{Binding YourTextProperty, NotifyOnTargetUpdated=True}" 
               TargetUpdated="YourTextEventHandler"/>
    
    0 讨论(0)
  • 2020-12-09 17:23

    Here's something you can use I picked up from Jerry Nixon and Daren May at the Microsoft Virtual Academy "Developing Universal Windows Apps with C# and XAML" and the code that contains the DependencyObject logic is here "(W8.1-WP8.1) UNIVERSAL APP FOR MVA".

    namespace App1.Behaviors
    {
    // <summary>
    /// Helper class that allows you to monitor a property corresponding to a dependency property 
    /// on some object for changes and have an event raised from
    /// the instance of this helper that you can handle.
    /// Usage: Construct an instance, passing in the object and the name of the normal .NET property that
    /// wraps a DependencyProperty, then subscribe to the PropertyChanged event on this helper instance. 
    /// Your subscriber will be called whenever the source DependencyProperty changes.
    /// </summary>
    public class DependencyPropertyChangedHelper : DependencyObject
    {
        /// <summary>
        /// Constructor for the helper. 
        /// </summary>
        /// <param name="source">Source object that exposes the DependencyProperty you wish to monitor.</param>
        /// <param name="propertyPath">The name of the property on that object that you want to monitor.</param>
        public DependencyPropertyChangedHelper(DependencyObject source, string propertyPath)
        {
            // Set up a binding that flows changes from the source DependencyProperty through to a DP contained by this helper 
            Binding binding = new Binding
            {
                Source = source,
                Path = new PropertyPath(propertyPath)
            };
            BindingOperations.SetBinding(this, HelperProperty, binding);
        }
    
        /// <summary>
        /// Dependency property that is used to hook property change events when an internal binding causes its value to change.
        /// This is only public because the DependencyProperty syntax requires it to be, do not use this property directly in your code.
        /// </summary>
        public static DependencyProperty HelperProperty =
            DependencyProperty.Register("Helper", typeof(object), typeof(DependencyPropertyChangedHelper), new PropertyMetadata(null, OnPropertyChanged));
    
        /// <summary>
        /// Wrapper property for a helper DependencyProperty used by this class. Only public because the DependencyProperty syntax requires it.
        /// DO NOT use this property directly.
        /// </summary>
        public object Helper
        {
            get { return (object)GetValue(HelperProperty); }
            set { SetValue(HelperProperty, value); }
        }
    
        // When our dependency property gets set by the binding, trigger the property changed event that the user of this helper can subscribe to
        private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var helper = (DependencyPropertyChangedHelper)d;
            helper.PropertyChanged(d, e);
        }
    
        /// <summary>
        /// This event will be raised whenever the source object property changes, and carries along the before and after values
        /// </summary>
        public event EventHandler<DependencyPropertyChangedEventArgs> PropertyChanged = delegate { };
    }
    }
    

    Usage XAML:

    <TextBlock Grid.Row="0"
           x:Name="WritingMenuTitle"
           HorizontalAlignment="Left"
           FontSize="32"
           FontWeight="SemiBold"
           Text="{Binding WritingMenu.Title}"
           TextAlignment="Left"
           TextWrapping="Wrap"/>
    

    Usage xaml.cs:

    Behaviors.DependencyPropertyChangedHelper helper = new Behaviors.DependencyPropertyChangedHelper(this.WritingMenuTitle, Models.CommonNames.TextBlockText);
    helper.PropertyChanged += viewModel.OnSenarioTextBlockTextChangedEvent;
    

    Usage viewmodel.cs:

    public async void OnSenarioTextBlockTextChangedEvent(object sender, DependencyPropertyChangedEventArgs args)
    {
    StringBuilder sMsg = new StringBuilder();
    
    try
    {
        Debug.WriteLine(String.Format(".....WritingMenuTitle : New ({0}), Old ({1})", args.NewValue, args.OldValue));
    }
    catch (Exception msg)
    {
        #region Exception
        .....
        #endregion
    }
    }
    
    0 讨论(0)
提交回复
热议问题