最近在学习WPF绑定的时候不明白DataContext的作用,经常导致数据绑定不上问题。

1,WPF应用程序有UI层和数据层,通过DataContext连接。

wpf 指定datatemplate 里面的样式 wpf datacontent_xml


需要注意的是View类的C#代码,并不是数据层。

2,未设置DataContext的UI对象将从其父对象继承其数据层

复制代码



一种是在View后台中:

var cont = new MainViewModle();
DataContext = cont;
一种是在XAML中:

<UserControl.Resources>

<vm:CalculatorViewModel x:Key=“calculatorVM” />

</UserControl.Resources>

在WPF中,应用程序有两层:UI层和Data层。这里新建一个项目说明哪些是UI层,哪些是数据层

wpf 指定datatemplate 里面的样式 wpf datacontent_Text_02


UI层很明显,就是用户看到的界面。但是数据层并不是下图所示:

wpf 指定datatemplate 里面的样式 wpf datacontent_Text_03


上图中是UI层view的后台代码。当然,你可以使用事件的方式把所有的业务逻辑代码写到这里,但是我们采用MVVM的时候业务逻辑是与这里解耦的,数据层是DataContext,此时并没有指定。

接下来我们新建个目录,然后添加个类文件:

然后指定VM类为DataContext:

数据绑定中使用DataContext 数据上下文,DataContext 属性是绑定的默认源,除非你特别声明另一个源。DataContext 属性没有默认源(从一开始就是 null),但是由于 DataContext 是通过控件层次结构向下继承的,因此可以为 Window 本身设置一个 DataContext,然后在所有子控件中使用它。

UI XAML 代码:

<Window x:Class=“WpfApp1.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:WpfApp1"

    mc:Ignorable="d"

    Title="测试 DataContext" Height="450" Width="800">

<Grid>

    <StackPanel Margin="15">

        <WrapPanel>

            <TextBlock Text="Window title:  " />

            <TextBox Text="{Binding Title, UpdateSourceTrigger=PropertyChanged}" Width="150" />

        </WrapPanel>

        <WrapPanel Margin="0,10,0,0">

            <TextBlock Text="Window dimensions: " />

            <TextBox Text="{Binding Width}" Width="50" />

            <TextBlock Text=" x " />

            <TextBox Text="{Binding Height}" Width="50" />

        </WrapPanel>

    </StackPanel>

</Grid>

后台绑定:

public partial class MainWindow : Window

{

    public MainWindow()

    {

        InitializeComponent();

        this.DataContext = this;

    }

}

这个例子的代码隐藏只添加了一行有趣的代码:在标准的 InitalizeComponent() 调用之后,我们将“this”引用分配给 DataContext,它只是告诉窗口我们希望自己成为数据上下文。在 XAML 中,我们使用这个事实来绑定到几个 Window 属性,包括 Title、Width 和 Height。由于窗口有一个 DataContext,它被传递给子控件,我们不必在每个绑定上定义一个源 - 我们只需使用这些值,就好像它们是全局可用的一样。

尝试运行示例并调整窗口大小 - 您将看到尺寸更改立即反映在文本框中。您也可以尝试在第一个文本框中编写不同的标题,但您可能会惊讶地发现此更改并未立即反映。相反,您必须在应用更改之前将焦点移动到另一个控件。