WPF中TextBox的Text更改的相关方法有两种
- TextChanged
- SourceUpdated
TextChanged
事件
在 TextBox 控件中的文本发生更改时使用 TextChanged 事件执行方法,但是这个有个问题,只要更改了就会触发,比如我要输入“12”,输入“1”就触发一次,输入“2”又触发一次,一共触发2次。感觉好像不太对。
<TextBox TextChanged="TextBox_TextChanged"/>
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
//TODO
}
Command
同样的,因为MVVM的思路,将它写成Command的方式,同样是更改了就会触发。因为其实它的内部也只是监听事件,当事件被触发的时候,执行Command。
<TextBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding TextChangedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
SourceUpdated
首先要看TextBox的Text这个依赖属性本身,他的UpdateSourceTrigger值是LostFocus。
TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(TextBox),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal,
OnTextPropertyChanged, CoerceText, isAnimationProhibited: true, UpdateSourceTrigger.LostFocus));
如果你去看UpdateSourceTrigger 枚举,他是这么说的:大多数依赖属性的默认值为 PropertyChanged,而 Text 属性的默认值为 LostFocus,它实际上是丢失焦点之后才调用OnTextPropertyChanged。
最终将Text绑定增加了一个属性NotifyOnSourceUpdated=True
,然后增加一个TextChangedCommand,如下所示,其中SourceUpdated很关键,他能在TextBox的Text丢失焦点,也就是当数据写完了,要更新源的时候触发TextChangedCommand
<TextBox Text="{Binding MyText, NotifyOnSourceUpdated=True}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SourceUpdated">
<i:InvokeCommandAction Command="{Binding TextChangedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
注意:这里这个TextChangedCommand是一个继承于ICommand接口的自定义接口,具体可以参考WPF自定义Command
public ICommand TextChangedCommand{ get; set; }
//构造函数里定义
TextChangedCommand= new SampleCommand(x => true, x =>
{
//TODO
});
特殊情况
当然了,如果你有特殊的结束字符,比如扫码枪的需求,他有个换行符作为结束字符,你可以用这个KeyBinding
<TextBox>
<TextBox.InputBindings>
<KeyBinding Command="{Binding TextChangedCommand}" Key="Return"></KeyBinding>
</TextBox.InputBindings>
</TextBox>
回答评论
问:请问这个SourceUpdated事件为啥要在失去TextBox的焦点才会执行,可以在TextBox更改Text的时候立即执行吗?
答:你直接用TextChanged就行了