前端代码的全称为Extensible Application Markup Language,简称XAML;
<Application.Resources>
</Application.Resources>
前端代码中x:Class="HelloWorld.App",它定义一个名叫App的类型,这个类型位于命令空间HelloWorld之中,与后端代码的namespace HelloWorld保持一致。
我们可以将x:Class和c#里面的class关键词看成是同一个东西,都表示定义某个类型。
WPF的世界里,DispatcherObject是终极父类,控件的父类们(准确的说,应该叫父类的父类的父类),至少有如下几个类型:
DispatcherObject
DependencyObject
Visual
UIElement
FrameworkElement
WPF几乎所有的控件都从上面这五个父类继承,它们的相互继承关系,形成了一棵树。
WPF启动流程及Dispatcher作用:DispatcherObject类使用作用
.NET为WPF准备了两个线程(WPF应用启动时),分别用于呈现界面(后台线程)和管理界面(UI线程)。后台线程一直隐藏于后台默默运行,我们感知不到,我们唯一能操作的就是UI线程。
绝大多数对象或控件都必须在UI线程上创建,而且,其它后台子线程不能直接访问UI线程上的控件,那么,后台线程非要访问UI线程的控件或对象,该怎么办呢?微软说,这样吧,我在UI线程上给你们提供一个中间商Dispatcher(调度员),将Dispatcher放到一个抽象类DispatcherObject,然后我向你保证,我所有的控件都从这个DispatcherObject类继承,这样当你们在后台线程中要访问控件时,就可以从控件中找到那位中间商Dispatcher,由中间商来完成你要对控件的操作访问。
在开发过程中,难免需要在后台线程中去操作控件,于是Dispatcher调度员提供了Invoke和BeginInvoke两个方法,供我们可以安全的访问UI线程中的控件。
修改UI内容后端代码
Task.Factory.StartNew(() =>
{
Task.Delay(3000).Wait();
button.Dispatcher.Invoke(() =>
{
button.Content = "www.wpfsoft.com";
});
});
利用Task工厂创建了一个子线程(后台线程),然后调用了button的Dispatcher调度员,其Invoke方法中传入了一个匿名函数,在这个匿名函数中去改变button按钮的Content属性。
UIElement类
UIElement基类为我们提供了一系列的鼠标、键盘和触摸事件,并提供了一些常用的依赖属性。它可以呈现继承它的所有控件,为控件布局时调整位置和大小,响应用户的输入,引发一系列的路由事件,并继承了IAnimatable动画接口,用于支持动画的某些方面。
DataContext 数据上下文
假定我们有一个View窗体,窗体有一个TextBox控件;又假如我们还有一个ViewModel实体,这个实体中有一个叫Name的属性。如果我们要将TextBox控件的Text属性和ViewModel实体的Name属性成功的建立绑定关系,必备的条件是什么?
由于View窗体继承于FrameworkElement类,所以每个窗体(或控件)都有一个叫DataContext的数据上下文属性。所以必备的条件是:ViewModel实体必须先赋值给View窗体的DataContext,ViewModel的Name属性才能绑定到TextBox控件的Text属性。换言之,领导之间要先搭好桥,下属和下属才好配合工作。这就是DataContext的概念和用途。
学习链接:https://www.wpfsoft.com/father