WPF TextBox绑定TextChanged事件出现RuntimeEventInfo转MethodInfo异常
问题原因
你遇到的报错本质是WPF 事件不支持直接绑定到 ViewModel 中的普通方法。
你在XAML中直接用TextChanged="{Binding Path=MinPauseTextChanged}"的写法是错误的:XAML解析器会把TextChanged识别为事件成员,反射获取到的是RuntimeEventInfo类型对象,但你绑定的是方法,解析器尝试将其转为MethodInfo调用时就触发了类型转换异常。
可选解决方案
方案1:后台代码中转调用(最简单,无需额外依赖)
直接在视图对应的后台代码(.xaml.cs)中声明事件处理方法,调用ViewModel的校验逻辑即可,符合MVVM规范中允许视图级代码处理视图相关逻辑的要求:
XAML代码:
<TextBox Grid.Row="0" Grid.Column="1" x:Name="TextBoxSettingMinPause" TextChanged="MinPauseTextChanged" Text="{Binding Path=MinPauseSetting}"/>
后台代码(.xaml.cs):
private void MinPauseTextChanged(object sender, TextChangedEventArgs args) { if (DataContext is 你的ViewModel类型 vm) { vm.MinPauseTextChanged(sender, args); } }
ViewModel代码调整:
把方法改为public即可:
public void MinPauseTextChanged(object sender, TextChangedEventArgs args) { // 原有校验逻辑 }
方案2:使用事件触发器绑定Command(纯MVVM无后台代码)
需要先安装Microsoft.Xaml.Behaviors.Wpf NuGet包,之后在XAML中引入行为命名空间,通过InvokeCommandAction绑定ViewModel中的ICommand:
XAML代码:
<Window x:Class="你的命名空间.你的窗口类" xmlns:i="http://schemas.microsoft.com/xaml/behaviors" <!-- 其他原有命名空间 --> > <TextBox Grid.Row="0" Grid.Column="1" x:Name="TextBoxSettingMinPause" Text="{Binding Path=MinPauseSetting}"> <i:Interaction.Triggers> <i:EventTrigger EventName="TextChanged"> <i:InvokeCommandAction Command="{Binding MinPauseTextChangedCommand}" PassEventArgsToCommand="True"/> </i:EventTrigger> </i:Interaction.Triggers> </TextBox>
ViewModel代码:
声明对应的ICommand属性即可:
// 你的Command实现类可以用RelayCommand或者DelegateCommand public ICommand MinPauseTextChangedCommand { get; } // 构造函数中初始化 public 你的ViewModel() { MinPauseTextChangedCommand = new RelayCommand<TextChangedEventArgs>(MinPauseTextChanged); } private void MinPauseTextChanged(TextChangedEventArgs args) { // 原有校验逻辑 }
方案3:使用WPF原生ValidationRule做输入校验(更适合格式校验场景)
针对你要校验00:00格式的需求,用WPF原生的验证规则更合适,无需绑定事件:
自定义校验规则类:
public class TimeFormatValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { var input = value as string; if (string.IsNullOrEmpty(input)) return new ValidationResult(false, "输入不能为空"); // 正则校验HH:mm格式 if (!System.Text.RegularExpressions.Regex.IsMatch(input, @"^([01][0-9]|2[0-3]):[0-5][0-9]$")) { return new ValidationResult(false, "请输入符合HH:mm格式的时间"); } return ValidationResult.ValidResult; } }
XAML绑定调整:
<TextBox Grid.Row="0" Grid.Column="1" x:Name="TextBoxSettingMinPause"> <TextBox.Text> <Binding Path="MinPauseSetting" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:TimeFormatValidationRule /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox>
校验不通过时控件会自动显示错误提示样式,你也可以自定义错误模板。
内容的提问来源于stack exchange,提问作者Jakob
相关产品推荐
相关产品推荐

