WPF数据绑定——Datacontext和itemsource的区别

来源:互联网 发布:ubuntu安装语言包 编辑:程序博客网 时间:2024/06/07 07:02

WPF 中 数据绑定 ItemSource和 DataContext的不同点:

(1)DataContext 一般是一个非集合性质的对象,而ItemSource 更期望数据源是 集合对象。

(2)DataContext 是 FrameworkElement 类中定义的一个依赖属性(Dependency property),ItemsSource是 在ItemsControl 类中定义的。所有继承自FrameworkElement 的类(控件)都可以使用DataContext属性并给其赋值,但我们只能给ItemsSource赋值为集合对象

(3)DataContext不能产生模板,它只能用来筛选出数据,供其它控件来绑定。而ItemsSource主要作用就是给模板提供数据。

(4)DataContext主要用来抓取一些子元素需要使用的数据,以保证子元素能够顺利的使用数据。ItemsSource不会用来分享数据,它只是对定义好的元素有效。
以上可参照博客:
https://www.cnblogs.com/flytigger/p/4113121.html

下面来看下Itemsource,这里没有用到DataConetext,下面这个例子说明了(1)中的ItemSource 更期望数据源是 集合对象:
后台代码:

public partial class MainWindow : Window    {               public MainWindow()        {            InitializeComponent();            List<string> listStrings = new List<string>();            for (int i = 0; i < 50; i++)            {                listStrings.Add(i.ToString());            }            listBox.ItemsSource = listStrings;        }    }

前台代码:

<Window x:Class="WpfApplication5.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"        xmlns:local="clr-namespace:WpfApplication5"        mc:Ignorable="d"        Title="MainWindow" Height="350" Width="525">    <Grid>        <ListBox Name="listBox"></ListBox>     </Grid></Window>

下面再来看看Datacontext和itemsource一起用的情况,从下面可以看出(2)中说明的情况,从调试中的代码可以看得更清楚一些,DataContext 一般是一个非集合性质的对象,然后前台的listbox绑定的是Datacontext中的MyListString的对象:
后台代码:

    public partial class MainWindow : Window    {            public List<string> MyListString { get; set; }           public MainWindow()        {            InitializeComponent();            List<string> listStrings = new List<string>();            for (int i = 0; i < 50; i++)            {                listStrings.Add(i.ToString());            }            MyListString = listStrings;            DataContext = this;        }    }

前台代码:

<Window x:Class="WpfApplication5.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"        xmlns:local="clr-namespace:WpfApplication5"        mc:Ignorable="d"        Title="MainWindow" Height="350" Width="525">    <Grid>        <ListBox Name="listBox" ItemsSource="{Binding Path=MyListString}"></ListBox>     </Grid></Window>

这里写图片描述

接着来看一个常用的绑定模式,DataContext直接绑定到类,itemsource直接绑定到类的字段:
首先来一个MainViewModel的类,并给予一个Student的字段,给字段赋值。

    public class MainViewModel    {        public List<Student> listStudent { get; set; }        public MainViewModel()        {            listStudent = new List<Student> { new Student("小王", 001), new Student("小张", 002), new Student("小李", 002) };        }    }    public class Student    {        public string Name { get; set; }        public int Id { get; set; }        public Student(string name, int id)        {            Name = name;            Id = id;        }    }

然后直接在前台用resourc绑定这个类,listbox的itemsource绑定这个类的字段Student。
前台绑定这个类的时候,实际上就相当于把这个类实例化了,listbox的itemsource只需要静态跟踪这个类的字段。

<Window x:Class="WpfApplication5.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"        xmlns:local="clr-namespace:WpfApplication5"        mc:Ignorable="d"        Title="MainWindow" Height="350" Width="525">    <Window.Resources>        <local:MainViewModel x:Key="mvm"/>    </Window.Resources>    <Grid>        <ListBox Name="listBox"  ItemsSource="{Binding Source={StaticResource mvm},Path=listStudent}"  DisplayMemberPath="Name"></ListBox>     </Grid></Window>

以上也可以换到后台表示:
换掉之后,前后台代码(这里需要在后台实例化):

public partial class MainWindow : Window    {        public MainWindow()        {            InitializeComponent();            MainViewModel mvm = new MainViewModel();                        listBox.ItemsSource = mvm.listStudent;        }    }
<Window x:Class="WpfApplication5.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"        xmlns:local="clr-namespace:WpfApplication5"        mc:Ignorable="d"        Title="MainWindow" Height="350" Width="525">    <Grid>        <ListBox Name="listBox"   DisplayMemberPath="Name"></ListBox>     </Grid></Window>

也可以稍微换一下绑定方式,不用Window.Resources,而改用Window.DataContext也可以:

<Window x:Class="WpfApplication5.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"        xmlns:local="clr-namespace:WpfApplication5"        mc:Ignorable="d"        Title="MainWindow" Height="350" Width="525">    <Window.DataContext>        <local:MainViewModel/>    </Window.DataContext>    <Grid>        <ListBox Name="listBox" ItemsSource="{Binding Path=listStudent}"  DisplayMemberPath="Name"></ListBox>     </Grid></Window>

其实,我更喜欢最后一个绑定方式,然而我并不知道这个绑定方式和Window.Resources绑定方式究竟有什么内在的区别。

原创粉丝点击