如何获取TextBox绑定的完整值?基于附加属性实现上下键增减数值
解决TextBox绑定带StringFormat时获取原始值进行增减的问题
你碰到的这个问题很典型——当TextBox的绑定设置了StringFormat后,Text属性只会显示格式化后的精简值,直接从这里拿自然得不到原始的完整数值。正确的思路是绕过TextBox的显示值,直接从绑定的源对象获取原始属性值,这样就能基于真实值做增减操作了。
下面是修改后的IncrementOrDecrementValue方法实现,核心是通过绑定表达式获取源数据:
private static void IncrementOrDecrementValue(DependencyObject sender, bool doIncrement) { if (sender is TextBox tb) { // 获取TextBox的Text属性对应的绑定表达式 var bindingExpression = tb.GetBindingExpression(TextBox.TextProperty); if (bindingExpression == null) { // 如果没有绑定,降级到原来从Text取值的逻辑 FallbackToTextValue(tb, doIncrement); return; } try { // 获取绑定的源对象和源属性名 var source = bindingExpression.DataItem; var sourceProperty = bindingExpression.ResolvedSourcePropertyName; // 读取原始的属性值 var originalValue = (double)source.GetType().GetProperty(sourceProperty).GetValue(source); var increment = GetSmallFloatIncrement(sender); // 计算新值 var newValue = doIncrement ? originalValue + increment : originalValue - increment; // 更新源属性值,双向绑定会自动同步到UI source.GetType().GetProperty(sourceProperty).SetValue(source, newValue); ValidateResult(sender); } catch (Exception ex) { // 处理异常:比如源属性不是double类型、反射失败等 FallbackToTextValue(tb, doIncrement); } } } // 保留原来的Text取值逻辑作为降级方案 private static void FallbackToTextValue(TextBox tb, bool doIncrement) { var increment = GetSmallFloatIncrement(tb); var text = tb.Text; double textBoxValue = 0.0; if (!string.IsNullOrEmpty(text)) { try { textBoxValue = Convert.ToDouble(text, FormatProvider); } catch (FormatException) { } } tb.Text = Convert.ToString(doIncrement ? textBoxValue + increment : textBoxValue - increment, FormatProvider); ValidateResult(tb); }
关键细节说明:
- 绑定表达式获取:通过
GetBindingExpression(TextBox.TextProperty)拿到Text属性的绑定信息,这是直接访问源数据的核心入口。 - 反射操作源属性:利用反射读取和修改源对象的属性值,完全绕开了TextBox的格式化显示,确保操作的是原始的绑定数据。
- 兼容性处理:加入了无绑定场景的降级逻辑,避免空绑定导致的程序崩溃,同时兼容原来的使用场景。
另外要注意:确保你的绑定是双向绑定(TextBox的Text绑定默认是双向的,但如果手动设置了Mode=OneWay,需要改成TwoWay),这样修改源属性后,UI会自动更新显示格式化后的新值。
内容的提问来源于stack exchange,提问作者tabina
相关产品推荐
相关产品推荐

