You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF中Button的SourceUpdated事件未触发,绑定源变更未同步至内容

WPF绑定问题:UI未更新且SourceUpdated事件未触发

问题代码

XAML文件

<Window x:Class="notify_on_source_updated.MainWindow"
        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:notify_on_source_updated"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Button x:Name="myButton" Click="myButton_Click" />
</Window>

代码后置文件

namespace notify_on_source_updated
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public string SourceText {get; set;}
        
        public MainWindow()
        {
            InitializeComponent();
            SourceText = "test";
            Binding binding = new Binding();

            binding.Source = SourceText;
            binding.NotifyOnSourceUpdated=true;
            
            myButton.SourceUpdated += myButton_SourceUpdated;
            myButton.SetBinding(ContentControl.ContentProperty, binding);
        }

        private void myButton_Click(object sender, RoutedEventArgs e)
        {
            SourceText = "changed";
        }

        private void myButton_SourceUpdated(object sender, DataTransferEventArgs e)
        {
            MessageBox.Show("Updated!");
        }
    }
}

疑惑与解答

1. 点击按钮后Button Content未更新为"changed"

原因:SourceText是普通CLR属性,未实现INotifyPropertyChanged接口。WPF的数据绑定依赖属性变更通知同步UI,当属性值修改时,如果没有触发PropertyChanged事件,WPF无法感知值的变化,因此不会更新UI。

2. SourceUpdated事件从未触发

原因:你混淆了SourceUpdated事件的触发逻辑:

  • SourceUpdated仅在目标控件的值回传给源对象时触发(比如TwoWay绑定下,用户修改TextBox的Text,值同步到源属性的场景)。
  • 你的绑定是默认的OneWay模式(仅源→目标同步),且操作是手动修改源属性值,这种场景下不会触发SourceUpdated。若要监听源属性更新到目标的动作,应该使用TargetUpdated事件,并设置binding.NotifyOnTargetUpdated=true。

修正方案

步骤1:实现INotifyPropertyChanged接口

让窗口类实现接口,给SourceText添加属性变更通知:

namespace notify_on_source_updated
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private string _sourceText;
        public string SourceText
        {
            get => _sourceText;
            set
            {
                if (_sourceText != value)
                {
                    _sourceText = value;
                    OnPropertyChanged(nameof(SourceText));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public MainWindow()
        {
            InitializeComponent();
            SourceText = "test";
            // 绑定源改为当前窗口实例,而非直接绑定SourceText字段
            Binding binding = new Binding(nameof(SourceText))
            {
                Source = this,
                // 启用目标更新通知(源→目标同步时触发)
                NotifyOnTargetUpdated = true
            };
            
            // 绑定TargetUpdated事件
            myButton.TargetUpdated += MyButton_TargetUpdated;
            myButton.SetBinding(ContentControl.ContentProperty, binding);
        }

        private void myButton_Click(object sender, RoutedEventArgs e)
        {
            SourceText = "changed";
        }

        private void MyButton_TargetUpdated(object sender, DataTransferEventArgs e)
        {
            MessageBox.Show("目标已更新!");
        }
    }
}

步骤2:明确绑定方向与事件的对应关系

  • OneWay绑定:源→目标,源变化时更新目标,对应TargetUpdated事件(需设置NotifyOnTargetUpdated=true)。
  • TwoWay绑定:源↔目标,目标变化回传源时触发SourceUpdated事件(需设置NotifyOnSourceUpdated=true),源变化更新目标时触发TargetUpdated。

若要测试SourceUpdated,可使用TextBox的TwoWay绑定示例:

// 构造函数中替换绑定逻辑
TextBox textBox = new TextBox();
Binding binding = new Binding(nameof(SourceText))
{
    Source = this,
    Mode = BindingMode.TwoWay,
    NotifyOnSourceUpdated = true
};
textBox.SourceUpdated += TextBox_SourceUpdated;
textBox.SetBinding(TextBox.TextProperty, binding);
// 将textBox添加到窗口布局
this.Content = textBox;

此时在TextBox中输入文本,值同步到SourceText时会触发SourceUpdated事件。


内容的提问来源于stack exchange,提问作者user32882

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 19:50:26