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

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>

WPF数据绑定——Datacontext和itemsource的区别_第1张图片

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

    public class MainViewModel
    {
        public List listStudent { get; set; }
        public MainViewModel()
        {
            listStudent = new List { 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绑定方式究竟有什么内在的区别。

你可能感兴趣的:(wpf)