2013-07-11 70 views
2

我在涉足WPF並注意到一個我以前從未見過的特性。在下面的示例中,我有兩個文本框綁定到代碼隱藏中的同一個DP。驗證錯誤導致綁定不更新

代碼隱藏:

public partial class MainWindow : Window 
{ 
    public string Text 
    { 
     get { return (string)GetValue(TextProperty); } 
     set { SetValue(TextProperty, value); } 
    } 

    public static readonly DependencyProperty TextProperty = 
     DependencyProperty.Register("Text", typeof(string), typeof(Window), new FrameworkPropertyMetadata("Hello")); 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 


} 

而XAML:

<TextBox> 
     <TextBox.Text> 
      <Binding RelativeSource = "{RelativeSource Mode=FindAncestor, AncestorType=Window}" Path="Text" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay"> 
       <Binding.ValidationRules> 
        <utils:RestrictInputValidator Restriction="IntegersOnly" ValidatesOnTargetUpdated="True"/> 
       </Binding.ValidationRules> 
      </Binding> 
     </TextBox.Text> 
    </TextBox> 
    <TextBox Name="TextBox" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, Mode=TwoWay, Path=Text, UpdateSourceTrigger=PropertyChanged}"/> 

我注意到,當我在包含失敗驗證(在這種情況下,任何東西了IntegerOnly驗證文本框輸入的東西這不是一個整數),底層的Text變量不會更新。 這是默認行爲嗎?它爲什麼這樣做?是否可以重寫?

Error example

+0

爲什麼要添加驗證,如果你要重寫它呢? –

+1

我不會,你是對的。但是可能會有一個模糊的用例,我需要查看代碼隱藏中的髒數據。 –

+0

您需要驗證的地方?你需要用戶嗎?或者你只是需要它的最終輸入?如果你需要後者,只需添加一個按鈕,然後彈出一個「MessageBox」來指出哪個字段是錯誤的,並且不會繼續,直到所有驗證都通過。看看[這個](http://stackoverflow.com/a/1268648/1466627)。 –

回答

0

設置有效性規則來CommitedValue,該值一直致力於源(msdn),之後將運行驗證的ValidationStep。

<utils:RestrictInputValidator Restriction="IntegersOnly" ValidationStep="CommitedValue" ValidatesOnTargetUpdated="True"/> 

編輯: 隨着validationstep設置爲CommitedValue或UpdatedValue,一個BindingExpression被髮送到驗證法而不是實際的數值。我不知道是否有另一種方式來獲得BindingExpression的值,但我做了一個擴展方法,它會得到它:

public static class BindingExtensions 
{ 
    public static T Evaluate<T>(this BindingExpression bindingExpr) 
    { 
     Type resolvedType = bindingExpr.ResolvedSource.GetType(); 
     PropertyInfo prop = resolvedType.GetProperty(
      bindingExpr.ResolvedSourcePropertyName); 
     return (T)prop.GetValue(bindingExpr.ResolvedSource); 
    } 
} 
+0

儘管我認爲這會起作用,但即使將限制更改爲限制=「無」(這實質上意味着不驗證),我的代碼也會拋出一個'InvalidCastException'。 –

+0

原來我回答得太快了,更新了我的答案 –