Dot-Net
WPF - MVVM - 文本框與視圖模型屬性不同步
我有一個帶有 TextBox 的 WPF 視圖,將 Text 欄位綁定到 ViewModel,UpdateSourceTrigger 設置為 PropertyChanged。在 ViewModel 的屬性設置器中,我有一個簡單的檢查來防止文本超過 10 個字元:
<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)。
問題是當我在 UI 中輸入第 11 個字元時,我沒有更新 _Name。我觸發了 PropertyChanged,我可以看到 get 訪問器被呼叫,它返回的字元串只有 10 個字元。但是,我的 TextBox 並沒有反映這一點;它仍然顯示 11 個字元的字元串。
最重要的是,如果在第 11 個字元上我將設置器中的文本更改為“錯誤”,並且觸發屬性發生了更改,則 TextBox 會更新以顯示更改後的文本。
那麼為什麼如果我將 setter 中的文本更改回之前的值,UI 不會反映這一點呢?
我知道有處理最大字元的替代方法,但為什麼這不起作用?
這不過是框架中的一個錯誤。中的
Text屬性TextBox確實獲得了您的新值,但 GUI 現在與它自己的TextProperty.ItemsControl當您想從 ViewModel 取消更改時,也會發生這種情況SelectedItem,這真的很煩人。但是,當您使用顯式時,不會發生此錯誤,
Binding因此可以將其用作解決方法。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”。<StackPanel> <TextBox Name="myTextBox" Text="{Binding Path=MyName, UpdateSourceTrigger=PropertyChanged}"/> <TextBlock Text="{Binding ElementName=myTextBox, Path=Text}"/> </StackPanel>