.NET: WPF Binding对数据的校验和转换以及多路Binding
一。校验
一般需要对target上的值进行校验。
xaml:
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Simple Binding" Height="135" Width="300"> <StackPanel x:Name="stackPanel" Background="LightBlue"> <TextBox x:Name="textBox1" Margin="5" /> <Slider x:Name="slider1" Minimum="0" Maximum="100" Margin="5" /> </StackPanel> </Window>
写一个RangeValidationRule类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Controls; namespace WpfApplication1 { class RangeValidationRule : ValidationRule { public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { ; if (double.TryParse(value.ToString(), out d)) { && d <= ) { return new ValidationResult(true, null); } } return new ValidationResult(false, "Validation Failed"); } } }
再在xaml.cs里这么写
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Data; using MySql.Data; using MySql.Data.Entity; using MySql.Data.MySqlClient; using System.Xml; using System.Xml.Linq; namespace WpfApplication1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Binding binding = new Binding("Value") { Source = this.slider1 }; binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; RangeValidationRule rvr = new RangeValidationRule(); binding.ValidationRules.Add(rvr); this.textBox1.SetBinding(TextBox.TextProperty, binding); } } }
如果在textbox里的数不在0到100范围里,其边框就会变成红色
在这里Source是slider1,target是textBox1。一般来说Source的数据都是正确的,而target的数据可能是用户输入的,有可能是不正确的,所以需要校验。上面的代码是不会对Source更新数据时进行校验的,如果说Source的数据也有可能有问题,我们就需要将校验条件的ValidatesOnTargetUpdated属性设为true
xaml:
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Simple Binding" Height="135" Width="300"> <StackPanel x:Name="stackPanel" Background="LightBlue"> <TextBox x:Name="textBox1" Margin="5" /> <Slider x:Name="slider1" Minimum="-10" Maximum="110" Margin="5" /> </StackPanel> </Window>
xaml.cs:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Data; using MySql.Data; using MySql.Data.Entity; using MySql.Data.MySqlClient; using System.Xml; using System.Xml.Linq; namespace WpfApplication1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Binding binding = new Binding("Value") { Source = this.slider1 }; binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; RangeValidationRule rvr = new RangeValidationRule(); rvr.ValidatesOnTargetUpdated = true; binding.ValidationRules.Add(rvr); this.textBox1.SetBinding(TextBox.TextProperty, binding); } } }
当slider的值小于0或者大于100时,textbox的边框就会变红,数字是不在0到100内的
如果要显示这个错误信息,需要加入侦听器,具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Data; using MySql.Data; using MySql.Data.Entity; using MySql.Data.MySqlClient; using System.Xml; using System.Xml.Linq; namespace WpfApplication1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Binding binding = new Binding("Value") { Source = this.slider1 }; binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; RangeValidationRule rvr = new RangeValidationRule(); rvr.ValidatesOnTargetUpdated = true; binding.ValidationRules.Add(rvr); binding.NotifyOnValidationError = true; this.textBox1.SetBinding(TextBox.TextProperty, binding); this.textBox1.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(this.ValidationError)); } private void ValidationError(object sender, RoutedEventArgs e) { ) { ].ErrorContent.ToString(); } } } }
二。 转换
简单的转换比如double转string WPF已经帮我们做了,但是像image转Enum之类的需要我们自己去写,我们要写一个类实现IValueConverter接口,里面有两个函数:Convert(source—>target)和ConvertBack(target->source)
先写一个plane类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WpfApplication1 { public enum Category { Bomber, Fighter } public enum State { Available, Locked, Unknown } class Plane { public Category Category { get; set; } public string Name { get; set; } public State State { get; set; } } }
再写实现IValueConverter的类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Data; using System.Globalization; namespace WpfApplication1 { public class CategoryToSourceConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { Category c = (Category)value; switch(c) { case Category.Bomber: return @"\Icons\Bomber.jpg"; case Category.Fighter: return @"\Icons\Fighter.jpg"; default: return null; } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public class StateToNullableBoolConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { State s = (State)value; switch(s) { case State.Locked: return false; case State.Available: return true; case State.Unknown: default: return null; } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { bool? nb = (bool?)value; switch(nb) { case true: return State.Available; case false: return State.Locked; case null: default: return State.Unknown; } } } }
xaml:
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Title="Simple Binding" Height="266" Width="300"> <Window.Resources> <local:CategoryToSourceConverter x:Key="cts" /> <local:StateToNullableBoolConverter x:Key="stnb" /> </Window.Resources> <StackPanel x:Name="stackPanel" Background="LightBlue"> <ListBox x:Name="listBoxPlane" Height="160" Margin="5"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Image Width="20" Height="20" Source="{Binding Path=Category, Converter={StaticResource cts}}"/> <TextBlock Text="{Binding Path=Name}" Width="60" Margin="80"/> <CheckBox IsThreeState="True" IsChecked="{Binding Path=State, Converter={StaticResource stnb}}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <Button x:Name="buttonLoad" Content="Load" Height="25" Margin="5" Click="buttonLoad_Click" /> <Button x:Name="buttonSave" Content="Save" Height="25" Margin="5.5" Click="buttonSave_Click" /> </StackPanel> </Window>
xaml.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Data; using MySql.Data; using MySql.Data.Entity; using MySql.Data.MySqlClient; using System.Xml; using System.Xml.Linq; using System.IO; namespace WpfApplication1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void buttonLoad_Click(object sender, RoutedEventArgs e) { List<Plane> planeList = new List<Plane>() { new Plane(){Category=Category.Bomber, Name="B-1", State=State.Unknown}, new Plane(){Category=Category.Bomber, Name="B-2", State=State.Unknown}, new Plane(){Category=Category.Fighter, Name="F-22", State=State.Unknown}, new Plane(){Category=Category.Fighter, Name="Su-47", State=State.Unknown}, new Plane(){Category=Category.Bomber, Name="B-52", State=State.Unknown}, new Plane(){Category=Category.Fighter, Name="J-10", State=State.Unknown}, }; this.listBoxPlane.ItemsSource = planeList; } private void buttonSave_Click(object sender, RoutedEventArgs e) { StringBuilder sb = new StringBuilder(); foreach(Plane p in listBoxPlane.Items) { sb.AppendLine(string.Format("Category={0}, Name={1}, State={2}", p.Category, p.Name, p.State)); } File.WriteAllText(@"C:\Users\Administrator\Desktop\Demo\WpfApplication1\WpfApplication1\PlaneList.txt", sb.ToString()); } } }
三。MultiBinding
这个例子验证textBox1和textBox2是不是相同,textBox3和textBox4是不是相同,如果相同则button is enabled
Converter:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Data; using System.Globalization; namespace WpfApplication1 { class LoginMultiBindingConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (!values.Cast<string>().Any(text => string.IsNullOrEmpty(text)) && values[].ToString() == values[].ToString() && values[].ToString() == values[].ToString()) { return true; } return false; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } }
xaml:
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Title="Simple Binding" Height="200" Width="300"> <StackPanel x:Name="stackPanel" Background="LightBlue"> <TextBox x:Name="textBox1" Height="23" Margin="5" /> <TextBox x:Name="textBox2" Height="23" Margin="5" /> <TextBox x:Name="textBox3" Height="23" Margin="5" /> <TextBox x:Name="textBox4" Height="23" Margin="5" /> <Button x:Name="button1" Content="Submit" Width="80" Margin="5"/> </StackPanel> </Window>
xaml.cs:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Data; using MySql.Data; using MySql.Data.Entity; using MySql.Data.MySqlClient; using System.Xml; using System.Xml.Linq; using System.IO; namespace WpfApplication1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.SetMultiBinding(); } private void SetMultiBinding() { Binding b1 = new Binding("Text") { Source = this.textBox1 }; Binding b2 = new Binding("Text") { Source = this.textBox2 }; Binding b3 = new Binding("Text") { Source = this.textBox3 }; Binding b4 = new Binding("Text") { Source = this.textBox4 }; MultiBinding mb = new MultiBinding() { Mode = BindingMode.OneWay }; mb.Bindings.Add(b1); mb.Bindings.Add(b2); mb.Bindings.Add(b3); mb.Bindings.Add(b4); mb.Converter = new LoginMultiBindingConverter(); this.button1.SetBinding(Button.IsEnabledProperty, mb); } } }
.NET: WPF Binding对数据的校验和转换以及多路Binding的更多相关文章
- WPF 基础 - Binding 对数据的转换和校验
1. Binding 对数据的转换和校验 Binding 中,有检验和转换关卡. 1.1 数据校验 源码: namespace System.Windows.Data { public class B ...
- WPF 之 Binding 对数据的校验与转换(三)
一.前言 Binding 的作用就是架在 Source 和 Target 之间的桥梁,数据可以在这座桥梁的帮助下来流通.就像现实中的桥梁会设置一些关卡进行安检一样,Binding 这座桥上也可以设 ...
- WPF中的数据验证
数据验证 WPF的Binding使得数据能够在数据源和目标之间流通,在数据流通的中间,便能够对数据做一些处理. 数据转换和数据验证便是在数据从源到目标 or 从目标到源 的时候对数据的验证和转换. V ...
- 背水一战 Windows 10 (20) - 绑定: DataContextChanged, UpdateSourceTrigger, 对绑定的数据做自定义转换
[源码下载] 背水一战 Windows 10 (20) - 绑定: DataContextChanged, UpdateSourceTrigger, 对绑定的数据做自定义转换 作者:webabcd 介 ...
- WPF基础知识、界面布局及控件Binding(转)
WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...
- WPF的ComboBox 数据模板自定义
WPF的ComboBox 有些时候不能满足用户需求,需要对数据内容和样式进行自定义,下面就简要介绍一下用数据模板(DataTemplate)的方式对ComboBox 内容进行定制: 原型设计如下: 步 ...
- 绑定: DataContextChanged, UpdateSourceTrigger, 对绑定的数据做自定义转换
介绍背水一战 Windows 10 之 绑定 DataContextChanged - FrameworkElement 的 DataContext 发生变化时触发的事件 UpdateSourceTr ...
- WPF基础知识、界面布局及控件Binding
WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...
- WPF中的数据模板(DataTemplate)(转)
原文地址 http://www.cnblogs.com/zhouyinhui/archive/2007/03/30/694388.html WPF中的数据模板(DataTemplate) ...
随机推荐
- 【ECshop错误集锦】解决ECShop发送邮件提示:Error: need RCPT command
ECShop发送邮件报错Error: need RCPT command,经检测,邮件服务器返回的真实错误是501 mail from address must be same as authoriz ...
- jboss4.2.3 SSL配置 + 生成数字签名
一.生成数字签名 1. 生成JKS文件 keytool -genkey -keyalg RSA -alias jbosskey -keystore jbosskey.jks 在win7系统中,该文件的 ...
- Java Messages Synchronous and Asynchronous
//The Consumer Class Consumes Messages in a Synchronous Manner public class Consumer { public static ...
- 使用dnspod进行简单的HTTP dns解析(防劫持)
https://www.dnspod.cn/httpdns/guide https://www.dnspod.cn/misc/D%2B免费版本接口说明.pdf 最简单的get接口去请求dnspod提供 ...
- php日期时间函数 整理
设定系统默认时区 date_default_timezone_get() $tz='America/Los_Angeles'; 返回系统默认时区 date_default_timezone_set($ ...
- 用angularJS实现Bootstrap的“手风琴”
主页面代码(发现Bootstrap官网上手风琴的实例样式有问题,在这里依然使用3.0.~版本) <!DOCTYPE html> <html ng-app="ct" ...
- How To Install Tinc and Set Up a Basic VPN on Ubuntu 14.04
Introduction In this tutorial, we will go over how to use Tinc, an open source Virtual Private Netwo ...
- OPENCV3.1+VS 坑我笔记!
1.调用findContours()函数程序崩溃. 原因: >>分析opencv源代码,跟踪测试,进入工程:opencv_imgproc 发现findContours函数 是调用 _fin ...
- github上所有大于800 star OC框架
https://github.com/XCGit/awesome-objc-frameworks#awesome-objc-frameworks awesome-objc-frameworks ID ...
- iOS UIWebView清除缓存
UIWebView清除Cookie: //清除cookies NSHTTPCookie *cookie; NSHTTPCookieStorage *storage = [NSHTTPCookieSto ...