Binding
Binding基础
绑定某个对象的属性值到控制上,写法如下:
public class Order : INotifyPropertyChanged//只要实现此接口
{
public event PropertyChangedEventHandler PropertyChanged;
private string orderNo;
public string OrderNo
{
get
{
return orderNo;
}
set
{
orderNo = value;
if (PropertyChanged != null)
{
//通知变化,OrderNo变化后控件就会自动更新值了
//OrderNo为对应的属性名
PropertyChanged.Invoke(this, new PropertyChangedEventArgs("OrderNo"));称
}
}
}
}
绑定方法: textBox.SetBinding(TextBox.TextProperty, new Binding("OrderNo") { Source = new Order() });
以其他控制作为源的写法:
<TextBox x:Name="textBox" Text="{Binding Path =Value,ElementName =slider}" V Width="120"/>
<Slider x:Name="slider" Width="179" Minimum="1" Maximum="100"/>
Binding的path,source灵活使用:
->path没有指定值代表是数据源的本身,如数据源本身为string int decimal类型时
->path一般是数据源对象的属性值, 如属性是集合多次层,如一国多省,省又多市,可这样写path=”/ProvinceList/CityList”
->source不写则会往控制的外层找DataContext的值作为它的Source
集合对象作为列表控制的ItemSource
只需要显示集合单个属性的写法
<ListBox x:Name="listBox" />
<TextBox x:Name="textBox" />
listBox.ItemsSource = students;
listBox.DisplayMemberPath = "Name";
textBox.SetBinding(TextBox.TextProperty, new Binding("SelectedItem.Id") { Source=listBox });
显示多个字段方法
<ListBox x:Name="listBox" >
<ListBox.ItemTemplate>
<DataTemplate> <!--固定写法-->
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}"></TextBlock>
<TextBlock Text="{Binding Name}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
listBox.ItemsSource = students;
使用集合类作为列表控制的ItemSource时一般考虑使用ObservableCollection<T>代表List<T>,因为ObservableCollection<T>实现了INotifyCollectionChanged接口,集合变化能立刻通知列表控制
ADO.NET对象作为数据源
如像DataTable DataSet对象直接用来绑定
用于显示数据源单个字段
DataTable dt = new DataTable();
listView.DisplayMemberPath = "Name";//要显示的字段
listView.ItemsSource = dt.DefaultView;//必须使用DefaultView,因为其实现了IEnumberable
用于显示数据源多个字段
<ListView x:Name="listView" >
<ListView.View>
<GridView>
<GridViewColumn Header="序号" DisplayMemberBinding="{Binding Id}" Width="120"/>
<GridViewColumn Header="姓名" DisplayMemberBinding="{Binding Name}" />
</GridView>
</ListView.View>
</ListView>
listView.ItemsSource = dt.DefaultView;
如果不想使用DefaultView则可以把对象赋给ListView的DataContext属性
DataTable dt = new DataTable();
listView.DataContext = dt;
//使用是个空的Binding,没有指定Source则会往外找DataContext
listView.SetBinding(ListView.ItemsSourceProperty, new Binding());
XML数据源
以xml格式的资源或xml文件作数据源
<ListView x:Name="listView" >
<ListView.View>
<GridView>
<GridViewColumn Header="序号" DisplayMemberBinding="{Binding XPath =@Id}" />
<GridViewColumn Header="姓名" DisplayMemberBinding="{Binding XPath =@Name}" />
</GridView>
</ListView.View>
</ListView>
上面使用的是XPath,且@代表是xml的元素的属性值,不加则是其子元素
var xdoc = new XmlDocument();
xdoc.Load(AppDomain.CurrentDomain.BaseDirectory+"student2.xml");
XmlDataProvider xpd = new XmlDataProvider();
xpd.Document = xdoc;
xpd.XPath = @"/StudentList/Student";//指定要暴漏出去的数据
//使用DataContext而非ItemsSource
listView.DataContext = xpd;
//这是一个没path,没source的binding则会直接使用DataContext
listView.SetBinding(ListView.ItemsSourceProperty, new Binding());
以下为窗体resource方式绑定,但没有通过测试
<Window.Resources>
<XmlDataProvider x:Key="xmlsource" XPath="/StudentList/Student">
<x:XData>
<StudentList>
<Student Id="1" Name="奥巴马2"></Student>
<Student Id="2" Name="库里"></Student>
</StudentList>
</x:XData>
</XmlDataProvider>
</Window.Resources>
<Grid>
<ListView x:Name="listView" DataContext="{StaticResource xmlsource}" >
<ListView.View>
<GridView>
<GridViewColumn Header="序号" DisplayMemberBinding="{Binding XPath=@Id}" Width="120"/>
<GridViewColumn Header="姓名" DisplayMemberBinding="{Binding XPath=@Name}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
Linq数据源
通过linq方式提供数据源
<ListView x:Name="listView" >
<ListView.View>
<GridView>
<GridViewColumn Header="序号" DisplayMemberBinding="{Binding Path=Id}" Width="120"/>
<GridViewColumn Header="姓名" DisplayMemberBinding="{Binding Path=Name}" />
</GridView>
</ListView.View>
</ListView>
常见的集合方式
var students = new List<Student>()
{
new Student() { Id=1,Name="奥巴马"},
new Student() { Id=1,Name="库里"},
};
//这里只要指定ItemsSource,xaml的bing即可以获取数据
listView.ItemsSource = from t in students select t;
通过DataTable方式
DataTable dt = new DataTable();
listView.ItemsSource = from row in dt.Rows.Cast<DataRow>())//转成实现了IEnumerable的DataRow
select new Student
{
Id=int.Parse(row["id"].ToString()),
Name=row["name"].ToString()
};
通过XML文件方式
<?xml version="1.0" encoding="utf-8" ?>
<StudentList>
<Class>
<Student Id="1" Name="奥巴马"></Student>
<Student Id="2" Name="库里"></Student>
</Class>
</StudentList>
//注意不是使用XmlDocument
XDocument xd = XDocument.Load(AppDomain.CurrentDomain.BaseDirectory + "student.xml");
listView.ItemsSource = from ele in xd.Descendants("Student")//Descendants可直接获取其下所有层次的student节点
select new Student
{
Id = int.Parse(ele.Attribute("Id").Value),
Name = ele.Attribute("Name").Value
};
ObjectDataProvider数据源
通常source都是来自对象的属性,但有时需要用到方法体返回值则用ObjectDataProvider
public class test
{
public int Add(int a, int b)
{
return a + b;
}
}
xaml
<TextBox x:Name="textBox1" />
<TextBox x:Name="textBox2" />
<TextBox x:Name="textBox3" />
cs代码
var odp = new ObjectDataProvider();
odp.ObjectInstance = new test();
odp.MethodName = "Add";
odp.MethodParameters.Add(1);
odp.MethodParameters.Add(2);
var bing1 = new Binding("MethodParameters[0]")//路径就是属性MethodParameters
{
Source =odp,
BindsDirectlyToSource =true,//UI收集的值直接写到source
UpdateSourceTrigger =UpdateSourceTrigger.PropertyChanged//一有更新立即回传到source
};
var bing2 = new Binding("MethodParameters[1]")
{
Source = odp,
BindsDirectlyToSource = true,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
var bing3 = new Binding(".") { Source = odp };//.数据源的本身
textBox1.SetBinding(TextBox.TextProperty, bing1);
textBox2.SetBinding(TextBox.TextProperty, bing2);
textBox3.SetBinding(TextBox.TextProperty, bing3);
RelativeSource数据源
用于指定窗体其他UI元素或自身的属性等作为数据源。
<DockPanel Name="KKK">
<DockPanel Name="HHH">
<Canvas Name="GGGG">
<TextBox x:Name="textBox22" />
</Canvas>
</DockPanel>
通过自身偏移量查找元素并作为数据源
var rela = new RelativeSource(RelativeSourceMode.FindAncestor);//查找方式:目标元素上级的方式
rela.AncestorLevel = 2;//以目标元素向外查找,符合指定类型的第2个元素作为数据源
rela.AncestorType = typeof(DockPanel);//元素类型
textBox22.SetBinding(TextBox.TextProperty, new Binding("Name") { RelativeSource = rela });//得到值"KKK"
XAML写法
<TextBox x:Name="textBox22" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=2,AncestorType={x:Type DockPanel}},Path=Name}" />
自身属性作为数据源
var rela = new RelativeSource(RelativeSourceMode.Self);//查找方式:自身
textBox22.SetBinding(TextBox.TextProperty, new Binding("Name") { RelativeSource = rela });//得到值"textBox22"
XAML写法
<TextBox x:Name="textBox22" Text="{Binding RelativeSource={RelativeSource Mode=Self},Path=Name}" >
Binding数据验证
<TextBox x:Name="textBox" />
<Slider x:Name="slider" Minimum="1" Maximum="100"/>
<Label x:Name="label" Content="Label" />
public va()
{
InitializeComponent();
var binding = new Binding("Value");
binding.Source = slider;//数据源为silder元素
//文本框输入值会更新slider
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
var vr = new TxtValidation();//此规则限制值为5才更新到slider
vr.ValidatesOnTargetUpdated = true;//值属性为true则双像都要验证,不加则只验证目标变化
binding.ValidationRules.Add(vr); //使用Add可以加N多规则
binding.NotifyOnValidationError = true;//true则由本元素向外传递验证错误信息,直到有接收错误的元素
textBox.SetBinding(TextBox.TextProperty, binding);
//用于接收验证错误信息
textBox.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(ValidaError));
}
private void ValidaError(object sender, RoutedEventArgs e)
{
var errors = Validation.GetErrors(textBox);
if (errors.Any())
{
//显示错误信息
label.Content = textBox.ToolTip = Validation.GetErrors(textBox)[0].ErrorContent.ToString();
}
}
//验证规则类
public class TxtValidation: ValidationRule
{
//主要是继承ValidationRule,并重写ValidationResult
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
int i = 0;
if (int.TryParse(value.ToString(), out i))
{
if(i!=5)
return new ValidationResult(false, "不是预期值");
}
else
{
return new ValidationResult(false, "格式不正确");
}
return new ValidationResult(true,"验证通过");
}
}
Binding数据转换
转换主要是写对应的转换类,通常需要用到转换的地方多为控制与绑定的字段类型不一致才需要转,可以双向转。主要是需在我们定义转换器,并实现 IValueConverter接口.如示例通过ListBox显示水果集合
//水果类
public class Fruits
{
/// <summary>
/// 分类
/// </summary>
public Category Category { get; set; }
/// <summary>
/// 选中状态 1=选中 2=不选中
/// </summary>
public int SelectState { get; set; }
}
public enum Category
{
Apple,
Banana
}
//水果种类转换器
public class CategoryConverter : IValueConverter
{
// 数据源转向目标时使用
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var category = (Category)value;
if (category == Category.Apple)
return "苹果";
else if (category == Category.Banana)
return "香蕉";
return "未知";
}
//目标转向数据源使用,当前转正不需要
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
//是否选中转换器
public class SelectStateConverter : IValueConverter
{
// 数据源转向目标时使用
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var selectState = (int)value;
if (selectState ==1)
return true;
return false;
}
//目标转向数据源使用
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var selectState = (bool)value;
if (selectState)
return 1;
return 2;
}
}
XAML代码
<Window.Resources>
<!--通过资源的方式定义转换-->
<local:CategoryConverter x:Key="cc" />
<local:SelectStateConverter x:Key="sc" />
</Window.Resources>
<Grid>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="sp" Orientation="Horizontal">
<CheckBox x:Name="checkBox" Content="{Binding Path=Category,Converter={StaticResource cc}}" IsChecked="{Binding Path=SelectState,Converter={StaticResource sc},UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Label x:Name="label1" Content="Label" />
<Button x:Name="button" Content="保存" H Click="button_Click"/>
</Grid>
C#代码:
var list = new List<Fruits>();
list.Add(new Fruits() { Category = Category.Apple, SelectState = 1 });
list.Add(new Fruits() { Category = Category.Apple, SelectState = 2 });
list.Add(new Fruits() { Category = Category.Banana, SelectState = 1 });
list.Add(new Fruits() { Category = Category.Banana, SelectState = 2 });
lb.ItemsSource = list;
多路Binding
即多个数据源或多个属性值组合起来满足自定义组合条件绑定到一个目标上。如两个文本框的值相等按钮才可用:
<TextBox x:Name="textBox" />
<TextBox x:Name="textBox1" />
<Button x:Name="button" IsEnabled="False"/>
public partial class MultiBinding2 : Window
{
public MultiBinding2()
{
InitializeComponent();
var binding1 = new Binding("Text") { Source = textBox };
var binding2 = new Binding("Text") { Source = textBox1 };
var mb = new MultiBinding() { Mode=BindingMode.OneWay};
//添加顺序是敏感的
mb.Bindings.Add(binding1);
mb.Bindings.Add(binding2);
mb.Converter = new EnableBtnConverter();
button.SetBinding(Button.IsEnabledProperty, mb);
}
}
public class EnableBtnConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values[0].ToString() == values[1].ToString();//不加ToString()居然不相等,为毛???
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Binding的更多相关文章
- org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): da.huying.usermanag ...
- WPF binding 参考
Introduction This is an article on WPF Binding Cheat Sheet. Some of the Binding won't work for Silve ...
- 十五天精通WCF——第一天 三种Binding让你KO80%的业务
转眼wcf技术已经出现很多年了,也在.net界混的风生水起,同时.net也是一个高度封装的框架,作为在wcf食物链最顶端的我们所能做的任务已经简单的不能再简单了, 再简单的话马路上的大妈也能写wcf了 ...
- Binding笔记
Binding基础 绑定某个对象的属性值到控制上,写法如下: public class Order : INotifyPropertyChanged//只要实现此接口 { public event ...
- Data Binding使用技巧
Data Binding 根据变量,自动赋值到各widget. How 1.编写layout文件,这里的layout为: act_data_bind_demo.xml 这里需要先准备变量 在具体的wi ...
- WPF之Binding初探
初学wpf,经常被Binding搞晕,以下记录写Binding的基础. 首先,盗用张图.这图形象的说明了Binding的机理. 对于Binding,意思是数据绑定,基本用法是: 1.在xmal中使用 ...
- [XAML]类似WPF绑定的Binding的读取方法
在WPF的XAML里,依赖属性可以使用基于BindingBase之类的MarkupExtensin 读取XAML时,会自动的把该BindingBase转换为BindingExpressionBase ...
- [ASP.NET MVC 小牛之路]15 - Model Binding
Model Binding(模型绑定)是 MVC 框架根据 HTTP 请求数据创建 .NET 对象的一个过程.我们之前所有示例中传递给 Action 方法参数的对象都是在 Model Binding ...
- Exception:HTTP Status 500 - org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
主要错误信息如下: HTTP Status 500 - org.apache.ibatis.binding.BindingException: Invalid bound statement (not ...
- UWP开发之Mvvmlight实践四:{x:bind}和{Binding}区别详解
{x:bind}是随着UWP被推出而被添加的,可以说是Win10 UWP开发专有扩展.虽然 {x:Bind} 缺少{Binding} 中的一些功能,但它运行时所花费的时间和使用的内存量均比 {Bind ...
随机推荐
- include的用法例子,以及include+merge的用法例子
[include+LinearLayout]的使用例子 AndroidIncludeLayout.java package com.AndroidIncludeLayout; import andro ...
- jQuery初探 jQuery选取和操纵元素的特点
jQuery初探 jQuery选取和操纵元素的特点 JavaScript选取元素 先来看看不用jQuery的时候我们是怎么处理元素选取的. JavaScript选取元素的时候,可以根据id获取元素,当 ...
- Linux0.11内核--文件系统理论知识
1.文件系统介绍 一个简单的文件系统大致需要这么几个要素: ● 要有地方存放Metadata: ● 要有地方记录扇区的使用情况: ● 要有地方来记录任一文件的信息,比如占用了哪些扇区等: ● 要有地方 ...
- python之(re)正则表达式下
知识储备: \w 匹配任何字母/数字,下划线 正则表达式进阶: re.match('com', 'comwww.runcomoob') re.search('\dcom', 'www.4comruno ...
- Git 工作流程
Git 作为一个源码管理系统,不可避免涉及到多人协作. 协作必须有一个规范的工作流程,让大家有效地合作,使得项目井井有条地发展下去.”工作流程”在英语里,叫做”workflow”或者”flow”,原意 ...
- oradebug/strace/pstack等分析数据库性能问题系列一
对于性能问题或者一些比较奇怪妖异的问题,有很多点可以着手去分析. 准备写一个系列关于用ash/dba_hist_active_sess_history,用oradebug,用linux命令strace ...
- 机器学习实战笔记(Python实现)-00-readme
近期学习机器学习,找到一本不错的教材<机器学习实战>.特此做这份学习笔记,以供日后翻阅. 机器学习算法分为有监督学习和无监督学习.这本书前两部分介绍的是有监督学习,第三部分介绍的是无监督学 ...
- 使用js 设置组合快捷键
使用js 设置组合快捷键 使用js设置快捷键的本质就是获得你要设置的这个键的keyCode 的值,如果要加ctrl,alt,shift,那么就添加一个ctrlkey,altKey,shiftKey来判 ...
- 使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟
使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟 Sqoop 大数据 Hive HBase ETL 使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟 基础环境 ...
- 交叉编译总结 libosscore.a libcurl.a libmysqlclient.a
把工程文件交叉编译到arm上运行,着实花费了一番功夫. 首先遇到的错误是 X uses VFP register arguments, B does not 百度了一下,发现是硬浮点和软浮点的问题,原 ...