如何在多个XAML文件的TextBox中复用同一个OnTextChanged方法
解决方案
下面提供几种无需复制代码即可在多个XAML文件中共享OnTextChanged逻辑的方案:
方案1:使用附加属性
创建静态辅助类,将文本处理逻辑封装为附加属性,通过XAML直接给TextBox启用该功能:
using System.Windows; using System.Windows.Controls; public static class TextBoxInputHelper { // 定义附加属性,标记是否启用逗号转句号功能 public static readonly DependencyProperty ReplaceCommaWithPeriodProperty = DependencyProperty.RegisterAttached( "ReplaceCommaWithPeriod", typeof(bool), typeof(TextBoxInputHelper), new PropertyMetadata(false, OnReplaceCommaWithPeriodChanged)); public static void SetReplaceCommaWithPeriod(TextBox element, bool value) { element.SetValue(ReplaceCommaWithPeriodProperty, value); } public static bool GetReplaceCommaWithPeriod(TextBox element) { return (bool)element.GetValue(ReplaceCommaWithPeriodProperty); } private static void OnReplaceCommaWithPeriodChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is TextBox textBox) { if ((bool)e.NewValue) { textBox.TextChanged += OnTextBoxTextChanged; } else { textBox.TextChanged -= OnTextBoxTextChanged; } } } // 共享的文本处理逻辑 private static void OnTextBoxTextChanged(object sender, TextChangedEventArgs e) { if (sender is TextBox myInput) { // 避免递归触发TextChanged myInput.TextChanged -= OnTextBoxTextChanged; myInput.Text = myInput.Text.Replace(",", ".").Trim(); myInput.CaretIndex = myInput.Text.Length; myInput.TextChanged += OnTextBoxTextChanged; } } }
在XAML中使用时,先引入对应命名空间(假设辅助类在YourNamespace.Helpers下):
xmlns:helpers="clr-namespace:YourNamespace.Helpers"
然后给TextBox设置附加属性:
<TextBox helpers:TextBoxInputHelper.ReplaceCommaWithPeriod="True"/>
方案2:使用Blend行为
如果项目已引用Microsoft.Xaml.Behaviors.Wpf(可通过NuGet安装),可以封装为行为,更符合MVVM风格:
using Microsoft.Xaml.Behaviors; using System.Windows.Controls; public class ReplaceCommaWithPeriodBehavior : Behavior<TextBox> { protected override void OnAttached() { base.OnAttached(); AssociatedObject.TextChanged += OnTextChanged; } protected override void OnDetaching() { base.OnDetaching(); AssociatedObject.TextChanged -= OnTextChanged; } private void OnTextChanged(object sender, TextChangedEventArgs e) { if (sender is TextBox myInput) { myInput.TextChanged -= OnTextChanged; myInput.Text = myInput.Text.Replace(",", ".").Trim(); myInput.CaretIndex = myInput.Text.Length; myInput.TextChanged += OnTextChanged; } } }
XAML中使用:
xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:behaviors="clr-namespace:YourNamespace.Behaviors" <TextBox> <i:Interaction.Behaviors> <behaviors:ReplaceCommaWithPeriodBehavior/> </i:Interaction.Behaviors> </TextBox>
方案3:继承页面基类
如果所有使用该TextBox的页面都可以继承同一个自定义基页面,可将逻辑放在基类中:
using System.Windows; using System.Windows.Controls; public class BasePage : Window // 若为UserControl则继承UserControl { protected void OnTextChanged(object sender, TextChangedEventArgs e) { var myInput = sender as TextBox; if (myInput == null) return; myInput.Text = myInput.Text.Replace(",", ".").Trim(); myInput.CaretIndex = myInput.Text.Length; } }
然后让你的页面继承这个基类:
public partial class YourPage : BasePage { public YourPage() { InitializeComponent(); } }
对应的XAML根节点也要修改:
<helpers:BasePage x:Class="YourNamespace.YourPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:helpers="clr-namespace:YourNamespace.Helpers"> <!-- 页面内容 --> <TextBox TextChanged="OnTextChanged"/> </helpers:BasePage>
内容的提问来源于stack exchange,提问作者online123
相关产品推荐
相关产品推荐

