wpf XAML xaml 进行 数据绑定,Resource DataContext ElementName
2017-06-07 17:04
886 查看
先做个声明:这里绑定都在前台实现,至于后台怎么写,那比前台简单多了,但更常用的是xaml中绑定。我们分析下最简单的字符串绑定来弄清楚原理,其他的类推就是。
数据绑定主要是要弄清楚两个东西,一个是源Source,一个是路径Path。
什么能够作为源Source呢:
CLR类型的单个对象
CLR类型的集合对象
DataTable和DataView
XML数据
依赖对象
FrameworkElement的DataContext
控件及ElementName
…
假如现在有一个最简单的需求:有一个窗口MainWindow,它里面有一个文本框(TextBox),Name为textBox,文本框的内容(Text)要绑定一个字符串。
好了,现在我们要考虑一个上面需求没提到的问题,该字符串是哪的字符串?
1.另外一个类Student(含公开属性Name)的实例化对象对应的Name
在哪实例化这个类Student呢?
在MainWindow.xaml.cs里,对不起,即使实例化了,xaml里无法直接访问cs里的实例化的对象。
在xaml里实例化,有个不错的选择就是通过声明资源(Resource)
这种方法测试是可行的。
那如果通过数据上下文DataContext的方式呢,怎么写
DataContext只要存在于要绑定的控件的本身或者其逻辑树父级以上就可以,我们还是定义在Grid上吧
这种方法测试也是可行的。
2.如果该字符串存在于当前页面,是当前页面的一个公开属性呢
我们先尝试用资源实例化
启动的时候报错了:
原因是资源不允许嵌套,就是说页面定义的资源不能是本身的实例。
再试试DataContext
跟上面报了相同的错,看来数据上下文也不能指定为自己的实例。
那就没招了吗?有的,直接将整个窗口(它也是FrameworkElement)作为Source,通过指定ElementName的方式
我们需要在cs里对Str赋值,否则绑定的是Str的默认值,这块我们这样理解,ElementName指定自己,那么就是实例化了一个MainWindow,它里面的属性都是取的默认值。
我们在构造里写 Str=“ZHAOLIU”,发现运行的文本框仍然为空,这是因为我们赋值是在界面初始化语句InitializeComponent();之后,
我们的属性又不具备更改通知功能,所以改变了值也不会起作用。下面我们就改造为可更改通知的。只需要继承接口INotifyPropertyChanged并实现他的约束就可以了。
经过测试是可以的。
3.如果字符串存在于另一个窗口,是其一个公开属性呢
我们再新建个窗口Window1
然后我们在MainWindow里实例化Window1试试
这是可以的。至此我们知道,资源中实例化一个对象,控件去绑定该对象的公开属性,只要一条,该对象不能是自己本身就ok。
使用DataContext也是可以的
ElementName呢,MainWindow拿不到Window1里的控件,就算你给Window1给了个名字,在MainWindow也不能以字符串直接拿到,不知道你们有没有见过将控件的值绑定到另一个页面的一个控件上的。
总结下:
数据绑定主要是要弄清楚两个东西,一个是源Source,一个是路径Path。
什么能够作为源Source呢:
CLR类型的单个对象
CLR类型的集合对象
DataTable和DataView
XML数据
依赖对象
FrameworkElement的DataContext
控件及ElementName
…
假如现在有一个最简单的需求:有一个窗口MainWindow,它里面有一个文本框(TextBox),Name为textBox,文本框的内容(Text)要绑定一个字符串。
好了,现在我们要考虑一个上面需求没提到的问题,该字符串是哪的字符串?
1.另外一个类Student(含公开属性Name)的实例化对象对应的Name
在哪实例化这个类Student呢?
在MainWindow.xaml.cs里,对不起,即使实例化了,xaml里无法直接访问cs里的实例化的对象。
在xaml里实例化,有个不错的选择就是通过声明资源(Resource)
1 <Grid> 2 <Grid.Resources> 3 <local:Student x:Key="stu" StuName="张三"/> 4 </Grid.Resources> 5 <TextBox Name="textBox" 6 Width="150" 7 Height="23" 8 BorderBrush="Black" 9 Text="{Binding Source={StaticResource stu},Path=StuName}"/> 10 </Grid>
这种方法测试是可行的。
那如果通过数据上下文DataContext的方式呢,怎么写
DataContext只要存在于要绑定的控件的本身或者其逻辑树父级以上就可以,我们还是定义在Grid上吧
1 <Grid Name="grid"> 2 <Grid.DataContext> 3 <local:Student StuName="李四"/> 4 </Grid.DataContext> 5 <TextBox Name="textBox" 6 Width="150" 7 Height="23" 8 BorderBrush="Black" 9 Text="{Binding Path=StuName}"/> 10 </Grid>
这种方法测试也是可行的。
2.如果该字符串存在于当前页面,是当前页面的一个公开属性呢
1 public partial class MainWindow : Window 2 { 3 public MainWindow() 4 { 5 InitializeComponent(); 6 } 7 private string str; 8 9 public string Str 10 { 11 get 12 { 13 return str; 14 } 15 16 set 17 { 18 str = value; 19 } 20 } 21 }
我们先尝试用资源实例化
1 <Window.Resources> 2 <local:MainWindow x:Key="str" Str="王五" /> 3 </Window.Resources> 4 <Grid Name="grid"> 5 <TextBox Name="textBox" 6 Width="150" 7 Height="23" 8 BorderBrush="Black" 9 Text="{Binding Source={StaticResource str}, Path=Str}" /> 10 </Grid>
启动的时候报错了:
原因是资源不允许嵌套,就是说页面定义的资源不能是本身的实例。
再试试DataContext
1 <Grid Name="grid"> 2 <Grid.DataContext> 3 <local:MainWindow Str="王五" /> 4 </Grid.DataContext> 5 <TextBox Name="textBox" 6 Width="150" 7 Height="23" 8 BorderBrush="Black" 9 Text="{Binding Path=Str}" /> 10 </Grid>
跟上面报了相同的错,看来数据上下文也不能指定为自己的实例。
那就没招了吗?有的,直接将整个窗口(它也是FrameworkElement)作为Source,通过指定ElementName的方式
1 <Window x:Class="Binding.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:local="clr-namespace:Binding" 6 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 7 Title="MainWindow" 8 Width="525" 9 Height="350" 10 mc:Ignorable="d" 11 Name="this"> 12 <Grid Name="grid"> 13 <TextBox Name="textBox" 14 Width="150" 15 Height="23" 16 BorderBrush="Black" 17 Text="{Binding ElementName=this, Path=Str}" /> 18 </Grid> 19 </Window>
我们需要在cs里对Str赋值,否则绑定的是Str的默认值,这块我们这样理解,ElementName指定自己,那么就是实例化了一个MainWindow,它里面的属性都是取的默认值。
我们在构造里写 Str=“ZHAOLIU”,发现运行的文本框仍然为空,这是因为我们赋值是在界面初始化语句InitializeComponent();之后,
我们的属性又不具备更改通知功能,所以改变了值也不会起作用。下面我们就改造为可更改通知的。只需要继承接口INotifyPropertyChanged并实现他的约束就可以了。
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using System.Windows; 8 using System.Windows.Controls; 9 using System.Windows.Data; 10 using System.Windows.Documents; 11 using System.Windows.Input; 12 using System.Windows.Media; 13 using System.Windows.Media.Imaging; 14 using System.Windows.Navigation; 15 using System.Windows.Shapes; 16 17 namespace Binding 18 { 19 /// <summary> 20 /// MainWindow.xaml 的交互逻辑 21 /// </summary> 22 public partial class MainWindow : Window, INotifyPropertyChanged 23 { 24 public MainWindow() 25 { 26 InitializeComponent(); 27 Str = "ZHAOLIU"; 28 } 29 private string str; 30 31 public event PropertyChangedEventHandler PropertyChanged; 32 33 public string Str 34 { 35 get 36 { 37 return str; 38 } 39 40 set 41 { 42 str = value; 43 if (PropertyChanged != null) 44 { 45 PropertyChanged(this, new PropertyChangedEventArgs("Str")); 46 } 47 } 48 } 49 } 50 }
经过测试是可以的。
3.如果字符串存在于另一个窗口,是其一个公开属性呢
我们再新建个窗口Window1
1 public partial class Window1 : Window 2 { 3 public Window1() 4 { 5 InitializeComponent(); 6 } 7 private string str; 8 9 public string Str 10 { 11 get 12 { 13 return str; 14 } 15 16 set 17 { 18 str = value; 19 } 20 } 21 }
然后我们在MainWindow里实例化Window1试试
1 <Window.Resources> 2 <local:Window1 x:Key="str" Str="王五" /> 3 </Window.Resources> 4 <Grid Name="grid"> 5 <TextBox Name="textBox" 6 Width="150" 7 Height="23" 8 BorderBrush="Black" 9 Text="{Binding Source={StaticResource str}, Path=Str}" /> 10 </Grid>
这是可以的。至此我们知道,资源中实例化一个对象,控件去绑定该对象的公开属性,只要一条,该对象不能是自己本身就ok。
使用DataContext也是可以的
1 <Window.DataContext> 2 <local:Window1 Str="麻子"/> 3 </Window.DataContext> 4 <Grid Name="grid"> 5 <TextBox Name="textBox" 6 Width="150" 7 Height="23" 8 BorderBrush="Black" 9 Text="{Binding Path=Str}" /> 10 </Grid>
ElementName呢,MainWindow拿不到Window1里的控件,就算你给Window1给了个名字,在MainWindow也不能以字符串直接拿到,不知道你们有没有见过将控件的值绑定到另一个页面的一个控件上的。
总结下:
相关文章推荐
- wpf数据绑定source和elementname的区别
- 译文:Silverlight 3.0 新功能之七 : XAML元素的数据绑定(XAML Element Databinding)
- WPF学习笔记:数据绑定与DataContext
- WPF数据绑定之DataContext
- wpf中数据绑定(Datacontext)的应用
- 如何使用 DataBinder.Eval(Container.DataItem,"num","{0:p}") 对DataList 进行数据绑定
- Windows Presentation Foundation(WPF)中的数据绑定(使用XmlDataProvider作控件绑定)
- SilverLight DataGrid 自定义列数据绑定 上下文代理器 DataContextProxy
- CYQ.Data 支持WPF相关的数据控件绑定(2013-08-09)
- CYQ.Data 支持WPF相关的数据控件绑定(2013-08-09)
- WPF学习1 DataGrid 采用模板列进行数据绑定
- C#Winform基础 datagirdview的datapropertyname给每列绑定数据
- D3中数据与DOM element绑定之data() enter() exit()浅析
- CYQ.Data 支持WPF相关的数据控件绑定.Net获取iis版本
- Bug--Error creating bean with name 'sessionFactory' defined in class path resource [data_context.xml
- WPF中在listview进行数据绑定,根据绑定数据调整一列的显示
- C#Winform基础 datagirdview的datapropertyname给每列绑定数据
- WPF中,怎么在后台代码进行数据绑定
- 【WPF学习日记】——Window的DataContext绑定ViewModel
- WPF的xaml中导入其他命名空间以及绑定类属性数据