如何在DataGridTemplateColumn内的控件上实现属性双向绑定
问题核心原因
你的代码存在4处关键配置遗漏/错误,按优先级排序如下:
- NumberBox的Value依赖属性CLR包装实现错误,依赖属性不能使用自定义私有字段存储值,WPF绑定系统会直接绕过CLR属性调用
GetValue/SetValue操作依赖属性,导致你定义的_value字段与实际绑定值不同步 - 未处理NumberBox内部TextBox的输入事件,用户输入的内容仅存储在TextBox的Text属性中,没有同步回Value依赖属性,自然无法传递到绑定的Data属性
- Value依赖属性未设置默认双向绑定规则,输入类控件默认需要双向绑定才能将输入值回传到源
- DataPoint类未实现INotifyPropertyChanged接口,会导致后台修改Data属性时前端无法同步更新
完整修改方案
1. 修改NumberBox.cs
public partial class NumberBox : UserControl { public event EventHandler ValueChanged; public NumberBox() { InitializeComponent(); // 订阅内部TextBox的文本变更事件 Container.TextChanged += Container_TextChanged; } // 依赖属性的CLR包装必须直接操作GetValue/SetValue,不能用自定义字段 public double Value { get { return (double)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } // 注册依赖属性时设置默认双向绑定 public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof(double), typeof(NumberBox), new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValuePropertyChanged) ); private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = d as NumberBox; control.Container.Text = e.NewValue?.ToString() ?? "0"; control.ValueChanged?.Invoke(control, EventArgs.Empty); } // 处理文本框输入,同步回Value依赖属性 private void Container_TextChanged(object sender, TextChangedEventArgs e) { if (double.TryParse(Container.Text, out double val)) { Value = val; } } }
2. 修改DataPoint.cs,实现INotifyPropertyChanged
using System.ComponentModel; using System.Runtime.CompilerServices; public class DataPoint : INotifyPropertyChanged { private double _data; public double Data { get => _data; set { _data = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
3. 可选:调整MainWindow.xaml绑定配置(如果需要实时同步输入,不需要等待失去焦点)
<BindingTest:NumberBox Value="{Binding Data, UpdateSourceTrigger=PropertyChanged}"/>
内容的提问来源于stack exchange,提问作者AmiralPatate
相关产品推荐
相关产品推荐

