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的更多相关文章

  1. org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):

    org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): da.huying.usermanag ...

  2. WPF binding 参考

    Introduction This is an article on WPF Binding Cheat Sheet. Some of the Binding won't work for Silve ...

  3. 十五天精通WCF——第一天 三种Binding让你KO80%的业务

    转眼wcf技术已经出现很多年了,也在.net界混的风生水起,同时.net也是一个高度封装的框架,作为在wcf食物链最顶端的我们所能做的任务已经简单的不能再简单了, 再简单的话马路上的大妈也能写wcf了 ...

  4. Binding笔记

    Binding基础  绑定某个对象的属性值到控制上,写法如下: public class Order : INotifyPropertyChanged//只要实现此接口 { public event ...

  5. Data Binding使用技巧

    Data Binding 根据变量,自动赋值到各widget. How 1.编写layout文件,这里的layout为: act_data_bind_demo.xml 这里需要先准备变量 在具体的wi ...

  6. WPF之Binding初探

    初学wpf,经常被Binding搞晕,以下记录写Binding的基础. 首先,盗用张图.这图形象的说明了Binding的机理. 对于Binding,意思是数据绑定,基本用法是: 1.在xmal中使用 ...

  7. [XAML]类似WPF绑定的Binding的读取方法

    在WPF的XAML里,依赖属性可以使用基于BindingBase之类的MarkupExtensin 读取XAML时,会自动的把该BindingBase转换为BindingExpressionBase ...

  8. [ASP.NET MVC 小牛之路]15 - Model Binding

    Model Binding(模型绑定)是 MVC 框架根据 HTTP 请求数据创建 .NET 对象的一个过程.我们之前所有示例中传递给 Action 方法参数的对象都是在 Model Binding ...

  9. 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 ...

  10. UWP开发之Mvvmlight实践四:{x:bind}和{Binding}区别详解

    {x:bind}是随着UWP被推出而被添加的,可以说是Win10 UWP开发专有扩展.虽然 {x:Bind} 缺少{Binding} 中的一些功能,但它运行时所花费的时间和使用的内存量均比 {Bind ...

随机推荐

  1. MVVM大比拼小结

    目前完成4篇源码分析文章: MVVM大比拼之knockout.js源码精析 MVVM大比拼之avalon.js源码精析 MVVM大比拼之vue.js源码精析 MVVM大比拼之AngularJS源码精析 ...

  2. FreeRTOS学习及移植笔记之一:开始FreeRTOS之旅

    1.必要的准备工作 工欲善其事,必先利其器,在开始学习和移植之前,相应的准备工作必不可少.所以在开始我们写要准备如下: 测试环境:我准备在STM32F103平台上移植和测试FreeRTOS系统 准备F ...

  3. css划隔横线的两种方法

    css划隔横线的两种方法  方法一:用DIV,代码如下:(推荐此方法)    <div style="width:800px;height:1px;margin:0px auto;pa ...

  4. 使用Maven自动部署Java Web应用到Tomcat服务器

    学习如何使用Maven,我推荐一本工具书,<maven the definitive guide>.在这本工具书手中,详细介绍了maven的使用思想,并且提供了从基本到复杂的具体项目应用. ...

  5. PHP面向对象——静态属性和静态方法

    静态属性 所谓静态属性,也就是这个属性对于这个类来说是唯一的,不管有多少个对象,只要它引用了一个静态对象,那么这些对象引用出来的值肯定是同一个. 静态变量不能使用->这种箭头符号,而是使用::这 ...

  6. Spring Boot 之 HelloWorld详解

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “以前是人放狗看家,现在是狗牵着人散步” — 随笔 一.Spring Boot 自述 世界上最好 ...

  7. 在GridView列表中使用图片显示记录是否包含附件

    在我的前面很多文章中,都介绍过通用附件模块的管理,本篇随笔主要介绍在一些应用模块中的列表展示中,包含附件的记录,在GridView列表界面中使用图标来快速显示是否有附件的情况. 1.通用附件模块的应用 ...

  8. C# 调用配置文件SQL语句 真2B!

    /********************************************************************************* ** File Name : SQ ...

  9. Java--&gt;实现群聊功能(C/S模式--TCP协议)

    --> Java 对TCP协议的支持: --> java.net包中定义了两个类ServerSocket 和Socket ,分别用来实现双向连接的server 端和client 端. -- ...

  10. 浏览器兼容的css hack

    <style> div{ background:green; /* for firefox */ *background:red; /* for IE6 */ } </style&g ...