WPF - MVVM - 文本框与 viewmodel 属性不同步 [英] WPF - MVVM - Textbox getting out of sync with viewmodel property
问题描述
我有一个带有 TextBox 的 WPF 视图,将 Text 字段绑定到一个 ViewModel,UpdateSourceTrigger 设置为 PropertyChanged.在 ViewModel 的属性设置器中,我有一个简单的检查,以防止文本超过 10 个字符:
I have a WPF view with a TextBox, binding the Text field to a ViewModel with UpdateSourceTrigger set to PropertyChanged. In the property setter in the ViewModel, I have a simple check to prevent the text from exceeding 10 characters:
<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
public string Name
{
get { return _Name; }
set
{
if (_Name != value)
{
if (value.Length <= 10)
{
_Name = value;
}
RaisePropertyChanged("Name");
}
}
}
如果未设置该值,我仍然使用 RaisePropertyChanged(它只是触发 PropertyChanged).
If the value isn't set, I still RaisePropertyChanged (which simply fires PropertyChanged).
问题是当我在 UI 中输入第 11 个字符时,我没有更新 _Name.我触发了 PropertyChanged,我可以看到 get 访问器被调用,它返回只有 10 个字符的字符串.但是,我的 TextBox 没有反映这一点;它仍然显示具有 11 个字符的字符串.
The problem is that when I type in the 11th character in the UI, I don't update _Name. I fire PropertyChanged, and I can see the get accessor get called and it returns the string with only 10 characters. However, my TextBox doesn't reflect this; it still shows the string with 11 characters.
最重要的是,如果在第 11 个字符上我将 setter 中的文本更改为ERROR",并且 fire 属性发生更改,则 TextBox 会更新以显示更改后的文本.
On top of that, is that if on the 11th character I change the text in the setter to "ERROR", and fire property changed, the TextBox DOES update to show the altered text.
那么为什么如果我将 setter 中的文本改回以前的值,UI 不会反映这一点?
So why is it that if I alter the text in the setter back to the previous value, the UI doesn't reflect this?
我知道有其他方法可以处理最大字符数,但为什么这行不通?
I know there are alternative ways of handling max characters, but why won't this work?
推荐答案
这只不过是框架中的一个错误.TextBox
中的 Text
属性确实获得了您的新值,但 GUI 现在与其自己的 TextProperty
不同步.当您想从 ViewModel 中取消 SelectedItem
的更改时,任何 ItemsControl
也会发生这种情况,这真的很烦人.
This is nothing but a bug in the framework. The Text
property in the TextBox
does get your new value but the GUI is now out of sync with its own TextProperty
. This also happends for any ItemsControl
when you want to cancel a change of SelectedItem
from the ViewModel and it's really annoying.
当您使用显式 Binding
时不会发生此错误,因此可以将其用作解决方法.
This bug doesn't happend when you use explicit Binding
though so this can be used as a workaround.
Xaml
<TextBox Text="{Binding Path=MyName,
UpdateSourceTrigger=Explicit}"
TextChanged="TextBox_TextChanged"/>
背后的代码
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
要验证 TextBox GUI 确实不同步,只需观察 TextBox.Text
的值.例如,TextBox
会说123456789___0",而 TextBlock
会说123456789".
To verify that the TextBox GUI indeed is out of sync, just observe the value of TextBox.Text
. The TextBox
will say "123456789___0" for example while TextBlock
says "123456789".
<StackPanel>
<TextBox Name="myTextBox"
Text="{Binding Path=MyName,
UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="{Binding ElementName=myTextBox, Path=Text}"/>
</StackPanel>
这篇关于WPF - MVVM - 文本框与 viewmodel 属性不同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!