WPF 中TextBox 增加輸入檢測,錯誤提示
先來總結下實現錯誤提示功能的幾個要點
1:binding 的ValidationRules
2 :Validation.ErrorTemplate
首先我們在界面添加一個TextBox, Text綁定到people對象的屬性age
public class People
{
public int age { get; set; }
public string name { get; set; }
}
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="30"Margin="75,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="155"> <TextBox.Text> <Binding UpdateSourceTrigger="PropertyChanged" Source="{StaticResource people}" Path="age" > <Binding.ValidationRules> <local:AgeValidationRule ></local:AgeValidationRule> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox>
這裏我們binding.ValidationRules 添加一個自己寫的錯誤驗證規則AgeValidationrule 代碼如下
public class AgeValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { int ret = 0; if(!int.TryParse(value.ToString(),out ret)) return new ValidationResult(false, "不是有效的數字"); if( ret >130 || ret<1) return new ValidationResult(false, "年齡必須是1-130之間"); return new ValidationResult(true, ""); } }
這樣,當Text的值變化時,就會觸發binding的驗證規則,調用到這裏面的validate函數。函數的第一個參數value傳的是我們綁定的值,第二個是時區信息,這裏我們不用管第二個。
此時,我們的TextBox已經有了自我檢查的能力。比如輸入一個a ,a不是數字,觸發validate函數時,驗證返回錯誤信息
ValidationResult(false, "不是有效的數字")
可以看到框框變紅了。這是因為使用了TextBox自帶默認的errorTemplate.
這樣的提示不夠明顯,還達不到我們的要求
下面我們來自己動手做一個錯誤提示模板
<Validation.ErrorTemplate> <ControlTemplate> <StackPanel Orientation="Horizontal"> <AdornedElementPlaceholder Name="customAdorner"></AdornedElementPlaceholder> <TextBox Text="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" Margin="10,0,0,0" BorderBrush="Red" Foreground="Red" VerticalContentAlignment="Center" > </TextBox> </StackPanel> </ControlTemplate> </Validation.ErrorTemplate>
分析一下這裏的代碼,Validation.ErrorTemplate,作為一個附加屬性,綁在TextBox上,當TextBox的Text 改變時,觸發binding的驗證規則 ValidationRules 。會調用到裏面對應的validate函數。
如果該函數返回結果為錯誤。那麽這個ErrorTemplate 就會顯示出來。
ErrorTemplate 中有一個很有意思的控件 AdornedElementPlaceholder ,它代表了整個ErrorTemplate 的宿主。假設我有一個名為XXX的控件,設置XXX的ErrorTemplate為上面的ErrorTemplate。那麽這個AdornedElementPlaceholder 就代表了這個XXX控件。這樣,我的ErrorTemplate就可以根據XXX控件的位置,來定位出StackPanel 和ErrorTemplate中textbox的位置。
即定位了我的錯誤提示內容的位置。
好,我們看到TextBox可以設置自己的附加屬性Validation.ErrorTemplate,應該說整個Validation都可以看成TextBox的附加屬性。那麽這個Validation裏還有一些我們能用到的東西。
當Bingding的驗證觸發後,會把裏面的錯誤信息保存到這個Validation的Errors列表中。這樣,我們就可以取出裏面的錯誤信息。即Validate函數返回的年齡必須是1-130之間。
所以,我們把錯誤提示用的TextBox的Text綁定到它的AdornedElementPlaceholder 對應控件的(Validation.Errors)[0].ErrorContent
Text="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
至此,大功告成
看一下效果
源碼路徑 : https://files.cnblogs.com/files/CSSZBB/TextBoxErrorHint.zip
WPF 中TextBox 增加輸入檢測,錯誤提示