DataSource的Property和TargetControl的DependencyProperty綁定,若是兩個Property的數據類型不一樣,則須要轉換。this
bind.Convert = new DataConverter():IValueConverter Convert屬性的類型是IValueConverter
public interface IValueConverter { object Convert(object value, Type outType, object parameter, CultureInfo culture); object ConvertBack(object value, Type outType, object parameter, CultureInfo culture); }
Convert用於將數據源屬性轉換成目標控件屬性。spa
value:數據源屬性值 outType:轉換後的數據類型 parameter:額外參數
ConvertBack用於將目標控件屬性轉換成數據源屬性。code
後臺數據源的SexCode,0表示女,1表示男,綁定到TextBlock。blog
class Sex { public int SexCode { get; set; } } Sex sex = new Sex(); Binding bind = new Binding(); bind.Source = sex; bind.Path = new PropertyPath("SexCode"); bind.Converter = new DataConvert(); BindingOperations.SetBinding(tbkSex, TextBlock.TextProperty, bind); class DataConvert : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { int sexCode = (int)value; if(sexCode == 0) { return "女"; } else { return "男"; } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
使用Binding的ConverterParameter的參數,使DataConvert複用,能被多個binding實例使用。繼承
class Sex { public int SexCode { get; set; } } class DataConvert : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { bool usage = (bool)parameter; if (usage) { int sexCode = (int)value; if (sexCode == 0) { return "女"; } else if (sexCode == 1) { return "男"; } else { return "保密"; } } else { int isCoder = (int)value; if(isCoder == 0) { return false; } else if(isCoder == 1) { return true; } else { return null; } } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } Sex sex = new Sex { SexCode = 3}; Binding bind = new Binding(); bind.Source = sex; bind.Path = new PropertyPath("SexCode"); bind.Converter = new DataConvert(); bind.ConverterParameter = true; BindingOperations.SetBinding(tbkSex, TextBlock.TextProperty, bind); bind = new Binding(); bind.Source = sex; bind.Path = new PropertyPath("SexCode"); bind.Converter = new DataConvert(); bind.ConverterParameter = false; cbxIsCoder.SetBinding(System.Windows.Controls.Primitives.ToggleButton.IsCheckedProperty, bind);
校驗是指改變目標控件的屬性,會校驗屬性的新值,合理則更新數據源,不合理則改變控件的樣式進行報錯,且不更新數據源。
Binding能夠有多個校驗規則,一條校驗規則是一個繼承自抽象類的ValidationRule的類實例。Binding的屬性ValidationRules,類型是Collection<ValidationRule>。繼承抽象類ValidationRule實現其Validation方法,返回類型是ValidationResult,校驗失敗,則ValidationResult.IsValid = false;ValidationResult.ErrorContent = "錯誤信息";校驗成功爲true和null。事件
public abstract class ValidationRule { protected ValidationRule(ValidationStep validationStep, bool validatesOnTargetUpdated); public abstract ValidationResult Validate(object value, CultureInfo cultureInfo); } public class ValidationResult { public ValidationResult(bool isValid, object errorContent); public static ValidationResult ValidResult { get; } public object ErrorContent { get; } public bool IsValid { get; } }
<TextBox Width="150" Validation.Error="ItemError"> <TextBox.Text> <Binding Source="{StaticResource myObject}" Path="PropertyB" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> <Binding.ValidationRules> <src:ValueIsNotNull ValidatesOnTargetUpdated="True" /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox>
校驗失敗,咱們須要改變控件樣式,來警告或提醒用戶,與該狀況相關的類是Invalidation。
控件有個Errors屬性,類型是Collection<ValidationError>,每一個校驗規則的返回值的ValidationResult的ErrorContent會填充到該集合。
Invalidation.GetErrors(目標控件)[0].ErrorContent.ToString()能拿到第一條檢驗失敗的錯誤信息。ip
this.AddHandler(Validation.Error,new RoutedEventHandler(this.ErrorHandler));
或者經過XAML設置 Validation.Error = "ErrorHandler"
2.
ToolTip = "{Binding RelativeSource = {RelativeSource self},Path=(Validation.Errors)[0].ErrorContent.ToString}"
3.設置ErrorTemplate。路由
<Grid> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBox x:Name="textText" MinHeight="70" MinWidth="200" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Validation.Error="textText_Error"> <TextBox.Resources> <local:Student Age="24" x:Key="dataSource"/> </TextBox.Resources> <TextBox.Text> <Binding Source="{StaticResource dataSource}" Path="Age" Mode="TwoWay" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:DataInvalidation ValidatesOnTargetUpdated="True"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> </StackPanel> </Grid>