.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) ...
随机推荐
- 【转】Cocos2d - 观察者模式NotificationCenter
http://shahdza.blog.51cto.com/2410787/1611575 [唠叨] 观察者模式 也叫订阅/发布(Subscribe/Publish)模式,是 MVC( 模型-视图-控 ...
- 20145319 《java程序设计》课程总结
20145319 <Java程序设计>课程总结 读书笔记链接总结 - 20145319 第一周学习总结 - 20145319 第二周学习总结 - 20145319 第三周学习总结 - 20 ...
- 常用ARM汇编指令
常用ARM汇编指令 [日期:2012-07-14] 来源:Linux社区 作者:xuyuanfan77 [字体:大 中 小] 在嵌入式开发中,汇编程序常常用于非常关键的地方,比如系统启动时初 ...
- Cloudera Hadoop什么是CDH及CDH版本介绍
本文引用自:Cloudera Hadoop什么是CDH及CDH版本介绍http://www.aboutyun.com/thread-6788-1-1.html(出处: about云开发) 云技术新兴的 ...
- Mongo中更新总结
mongo中的更新其实也可以当做添加来使用 mongo中跟新有几种方式 save.update.upsert 执行save的时候如果这个文档有_id这个参数,save 会调用 upsert,否则会调用 ...
- c# ToString() 用法
string tempa = Convert.ToString(31, 2);//将10进制数31转换为2进制字符串. string strNums = int.Parse(tempa).ToStri ...
- 是什么在.NET程序关闭时阻碍进程的退出?
在平时使用软件或是.NET程序开发的过程中,我们有时会遇到程序关闭后但进程却没有退出的情况,这往往预示着代码中有问题存在,不能正确的在程序退出时停止代码执行和销毁资源.这个现象有时并不容易被察觉,但在 ...
- Magento PHP Extension "curl" must be loaded解决方法
我记得我第一次在xampp装magento的时候,进入后台时提示PHP Extension "curl" must be loaded 在网页上查了下原因和解决方法,发现是mage ...
- oracle 把一个用户的表结构导入到另一个用户下
create table AM_CONTENTS as select * from bizdata008.AM_CONTENTS where 1=2
- Fiddler-002-常用配置修改
日常在应用 Fiddler 进行网络抓包时,有时需要查看服务器的类型或者其他信息,此文主要讲述实际应用中针对 Fiddler 进行的定制化配置,以方便日常的工作学习. 第一:显示服务器的类型和请求域名 ...