WPF - MVVM - 文本框不同步与视图模型属性
我有一个WPF视图一个文本框,文本字段绑定到视图模型与UpdateSourceTrigger设置的PropertyChanged。在属性二传手在视图模型,我有一个简单的检查,以prevent不超过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).
现在的问题是,当我输入用户界面中的11字,我不更新_Name。我火的PropertyChanged,我可以看到get访问被调用,它返回字符串只有10个字符。然而,我的文本框没有反映这一点;它仍然显示的字符串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号角色,我改变文本的制定者为错误,而火属性变化,文本框会更新以显示修改的内容。
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.
那么,为什么,如果我改变了二传手回到previous值的文本,用户界面没有反映这一点?
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?
这是什么,但在框架中的一个错误。该文本
属性在文本框
并获得新的价值,但GUI现在不同步自己的 TextProperty
。这也happends任何的ItemsControl
如果您想取消的SelectedItem
从视图模型的变化,它是真烦人。
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.
当你使用明确的绑定
虽然因此这可以作为一种解决方法。
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"/>
$ C $后面ç的
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
要验证文本框界面的确是不同步的,只是观察 TextBox.Text
的价值。该文本框
会说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>