如何检测TextBlock的Text属性是否发生改变?

32
有没有办法使用事件检测TextBlock元素的Text属性变化?(我试图为DataGrid中更改了Text属性的TextBlock提供突出显示的动画效果)

1
看一下这个:https://dev59.com/XHA85IYBdhLWcg3wCfLm#2964694 - SepehrM
6个回答

46

其实比那还要容易!虽然回答晚了,但更加简单。

// assume textBlock is your TextBlock
var dp = DependencyPropertyDescriptor.FromProperty(
             TextBlock.TextProperty,
             typeof(TextBlock));
dp.AddValueChanged(textBlock, (sender, args) =>
{
    MessageBox.Show("text changed");
});

3
你把dp.AddValueChanged放在哪儿了? - wbt11a
你可以将它放在代码后面。例如,在“InitializeComponent()”下面。 - Welcor
1
请记住,这也会引入内存泄漏!您需要确保取消订阅。 - DerApe

27
这就像是 bioskope 回答中链接里的代码,但更简化了。你需要使用 TargetUpdated 事件,并在绑定中添加 NotifyOnTargetUpdated=True
<TextBlock Text="{Binding YourTextProperty, NotifyOnTargetUpdated=True}" 
           TargetUpdated="YourTextEventHandler"/>

2
通过使用代码后台事件,在我看来,这应该是正确的答案。 - Ted Corleone
不同意。Bioscope的答案有一个优点,就是不需要后台代码。知道这个答案也很好,但这里没有“正确的答案”。 - Bent Tranberg

10

据我所了解,TextBlock中没有textchanged事件。根据您的要求,我觉得重新模板化文本框也不是可行的解决方案。从我的初步搜索中,这里似乎是一个可能的解决方案。

<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>

这正是我想做的。非常感谢。 - John Parker

1
将Text属性绑定到一个具有事件触发器的DependencyProperty上:
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);
}

在XAML中绑定到TextBlock的文本属性:
<TextBlock  
 Text="{Binding SomeProperty, UpdateSourceTrigger=PropertyChanged}"  
     th:TextBlockBehavior.TextBoxText="{Binding Text, 
     RelativeSource={RelativeSource Self}}" />

0

这里有一些你可以使用的东西,我从Jerry Nixon和Daren May在Microsoft Virtual Academy学到了 "使用C#和XAML开发通用Windows应用程序",包含DependencyObject逻辑的代码在这里 "(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 { };
}
}

使用 XAML:

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

在 xaml.cs 中的使用:

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

使用 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接