2012-03-15 24 views
0

我想允許用戶只輸入由TextBox綁定驗證規則驗證的文本。我想出了一個辦法:如何在不更新綁定目標的情況下驗證值?

public static void PreviewTextChanged(
    object sender, 
    PreviewTextChangedEventArgs e) 
{ 
    var textBox = e.Source as TextBox; 
    var bindingExpression = textBox.GetBindingExpression(TextBox.TextProperty); 
    if (!ReferenceEquals(null, bindingExpression)) 
    { 
     // save original parameters for possible restoration 
     var originalSelectionStart = textBox.SelectionStart; 
     var originalSelectionLength = textBox.SelectionLength; 
     var originalText = textBox.Text; 

     // check validation 
     textBox.Text = e.Text; 
     if (!bindingExpression.ValidateWithoutUpdate()) 
     { 
      // restore original values 
      textBox.Text = originalText; 
      bindingExpression.UpdateSource(); 
      textBox.SelectionStart = originalSelectionStart; 
      textBox.SelectionLength = originalSelectionLength; 
     } 
     else 
     { 
      // correct the selection 
      var selectionStart = originalSelectionStart + 
       originalSelectionLength + 
       e.Text.Length - 
       originalText.Length; 
      textBox.SelectionStart = Math.Max(selectionStart, 0); 
      textBox.SelectionLength = 0; 
     } 

     e.Handled = true; 
    } 
} 

上面的代碼工作。但是,如果我能找到一種方法來檢查新值是否有效,而不更新綁定目標,它會簡單得多,而且更容易出錯。有一個嗎?

回答

0

我認爲在這種情況下在Binding Converters上繼電器更容易。 每次將數據分配到綁定字段時,都會調用converter。 在它的內部方法中,您可以驗證數據的輸入,並基於驗證結果返回或舊數據(導致驗證失敗)從ModelView恢復或接受它,以防驗證成功。

希望這會有所幫助。

+0

我理解你的想法,但是如何從轉換器中訪問舊數據? – 2012-03-15 19:38:53

+0

「舊」數據是尚未受應用於UI的更改影響的數據。正確嗎?所以在你的'ModelView'中你有一個在UI上可視化的數據。用戶在綁定字段上更改了某些內容。所以會發生什麼,它改變了'ModelView'關聯屬性上設置的值。但**之前**發生的轉換器調用。轉換器的返回值將是分配給'ModelView'和'UI'的值。因此,如果您在此時進行驗證,則可以控制在「UI」和「ModelView」圖層之間傳遞的值。 – Tigran 2012-03-15 19:43:15

相關問題