Dot-Net

WPF - MVVM - 文本框與視圖模型屬性不同步

  • January 15, 2015

我有一個帶有 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>

引用自:https://stackoverflow.com/questions/10837679