学习目标:
提示:WPF与.NET编程(第2章)
- 应用程序模型
- 对象模型
- 逻辑树与可视化树
- 用户界面元素
- 事件
- 命令
- 导航
学习时间:
规划:
- 周一至周五
- 周六上午 9 点-下午 6 点
- 周日上午 9 点-下午 6 点
学习产出:
-
事件处理
说明:WPF需要Single Threaded Apartment(STA)线程,所以必须为Main方法添加[System.STAThread()]特性。
-
WPF开发概念
-
Application对象
Activated事件创建一个新的事件处理程序,这些方法及其对应的事件
事件 方法 描述 Activated OnActivated 窗口由系统激活 Deactiveated OnDeactivated 窗口由系统撤销激活 SessionEnding OnSessionEnding 当前一个用户对话结束或操作系统终止时(例如注销或关机)引发 Exit OnExit 所有窗口都销毁时引发 Startup OnStartup 在所有窗口创建之前或执行导航之前引发 -
获取Application对象引用
***注意:***虽然XAML可以在不同的应用程序类型之间进行转换,但由于安全性的限制WPF的一些特征在默认的XBAP中,是不充许的。
在WPF中的使用的窗口对象有三个层次:- Window
- NavigationWindow
- Page
事件 描述 Activated 窗口已经被激活 Closed 窗口已经关闭 Closing 窗口正在关闭 ContentRendered 窗口中的内容已经渲染。当窗口中没有内容时该事件不会被引发 Deactivated 窗口已经被撤销激活 LoactionChanged 窗口的位置已经改变 StateChanged 窗口的状态(最大化、最小化与正常)已经改变 注意: Application对象的窗口集合只包含在Application对象所在线程中创建的窗口。如果一个窗口是由其他线程创建的,该窗口就不能添加到Application对象的窗口集合中,并且也不能通过Application对象来访问。
NavigationWindow对象是针对导航应用程序设计的,并且继承自Window基类。它提供了下列功能:
- 在XAML页面之间导航
- 保存和管理导航记录的历史跟踪机制。
- 通过Navigation对象编程访问窗口的各种成员。
WPF平台基于异步执行模型,所以Navigate方法在开始导航处理时,就返回到其调用点。在这一调用点,上述步骤所引发事件的状态由NavigationService对象管理。导航处理的具体事件如表:
事件 描述 Navigating 导航处理已经开始。要停止后面的导航,可惟取消该事件 NavigationProgress 该事件提供导航处理完成的状态。处理该事件可以为应用程序提供导航处理的状态 Navigated 导航目标已经标识且已经请求下载,并且下载也已经开始。XAML页面逻辑树部分内容已经通过解析,并且已经潜在地与页面关联在一起了 LoadCompleted 页面已经全部下载并解析完毕,并且可以相应地进行渲染 事件处理
对于WPF中的事件处理,有两种选择:
- XAML事件处理程序
- 程序事件处理程序
1.窗口事件及其描述
事件 描述 Activated 窗口已经被激活 Closed 窗口已经关闭 Closing 窗口正在关闭 ContentRendered 窗口中的内容已经渲染 Deactivated 窗口已经被撤销激活 LocationChanged 窗口的位置或源点(Source)已经改变 StateChanged 窗口的状态已经改变。三个窗口状态分别是最大化、最小化与正常状态 2.事件传递
事件传递有三种类型:
- 下传
- 上传
- 直接传递
注意: 只有在控件可视化树的标记中明确引用的事件,才会被包含进被引发的事件顺序表中。所有省图的事件程序表示将失去处理事件的机会。
3.使用控件
控件嵌套- 控件嵌套控件,充许可视化树的概念。
- 具有可视化树控件可以为树中的每个控件引发大量的事件,从而提供一个到时候加扩展和灵活的事件处理模弄,称为事件传递(Event routing).
- 控件可以使用传递命令来调用在控件和用户界面元素之间的共享功能。
- 传递的命令能够提供一个单一的激活行为,只访问一次就可以妨行多个不同的函数或功能
WPF控件
利用互操作功能使用Windows窗体控件- Button
- CheckBox
- ComboBox
- ContextMenu
- DockPanel
- Expander
- Grid
- GridSplitter
- GroupBox
- HorizontalScrollBar
- Image
- Label
- ListBox
- ListView
- MediaPlayer
- Menu
- MonthCalendar
- OpenFileDialog
- PageSetupDialog
- PasswordBox
- Pointer
- PrintDialog
- ProgressBar
- RadioButton
- RichTextBox
- SaveFileDialog
- ScrollViewer
- Slider
- TabItem
- TextBox
- ToolBar
- ToolTip
- TreeView
- UserControl
- VerticalScrollBar
- Window
- WrapPanel
在WPF中使用了如下四种类型的控件:
- 内容控件(Content controls)—— 内容控件基本上是限定范围的控件,允许显示单一内容(singular content)即一个内容控件只提供一个基本数据元素,如:字符串、整数或图像内容,除非面板控件用做它的主要子元素。如果使用面板,那么面板中任何嵌套控件中的内容都有可能存在,尽管面板控件本身只包含一个单独的内容控件子元素。Button、CheckBox以及RadioButton等都是内容控件。内容控件不包含header属性和选项集合。
- 选项控件(Items controls)—— 选项控件用于包含值或元素的列表。选项控件包括ComboBox、ContextMenu、 Menu、 ListBox、及TabControl。这些控件包含选项集合,但是没有Content属性或任何Header属性。
- Headered选项控件(Headered items controls)—— Headered选项控件用于为其子控件显示一个主要的、父级的控件或对象。菜单项是Headered选项控件的一个很的例子。
- Headered内容控件(Headered Content controls)—— Headered 内容控件是包含唯一一个Header属性和一个Content属性的控件。Header属性包含一个文本值,并且Content属性只包含一个内容项。例如Content属性的值可以是Expander或TabItem控件的特定实例。
附属属性系统
附属属性提供了以下功能:
- 为控件提供继承其容器元素属性(例如坐标、尺寸等)的能力。
- 对象无关(Object-independent)存储
- 跟踪元素的变化,以使用undo命令控制控件或元素的状态。复杂数据绑定。
- 为一个控件构造动画程序
附属性例: Width 、 Background、 Text 等,每个附属属性都有一个相应的静态DependencyProperty域。父元素可以自己动将它们的附属属性传递给其子元素。
附加属性例: DockPanel控件将Dock属性作为附加属性,并注册到附属属性系统中。通过这种方法,DockPanel控件的子元素能够正确地计算它们的位置。可以为任何通够使用附加属性的控件设置附加属性。
4.控件组成
控件由XAML标记和后台代码程序逻辑构成。
5.样式
- 控件模板:,本质上是元素、故事板与触发器的集合,最终为一个或多个控件提供可视化外观
- 控件样式:, 用于共享和构造可重用的格化指示,在XAML页面中使用。包含控件的可视化格式信息,用于在外部显示控件。
6.可视化树
7.命令
本质上,命令(commands)是实现共享动作的一种手段,命令被认为是传递的,其部分原因是它们跟随了WPF中事件下传和上传的路线。第次命令被执行,都需要钩住它的下传和上传事件。当在应用程序中使用RoutedCommand类时,它将引发PreviewExecuteEvent与ExecuteEvent事件。PreviewExecuteEvent提供了一个下传事件来抢先处理还示到达的事件,相反,ExecuteEvent提供相应的上传事件来访问紧跟在事件触发之后的逻辑。RoutedCommand类还提供了一个可重载的Execute方法以供使用,可以将一个特定的目标元素作为参数传递给该方法以提供上下文。
类 | 描述 |
---|---|
ApplicationCommands | 包含公共的剪贴板和文件级的命令,例如File/Open、File/New等 |
ComponentCommands | 允许向上滚动或向下滚动、移动到文本选择的头部或移动到文本选择的尾部 |
EditCommands | 提供编离辑功能,例如字体的格式化等 |
MediaCommands | 提供与多媒体相关的操作,例如播放、暂停和停止等 |
声明命令
命令和事件之间的基本区别是命令不与控件相关,因为有许多元素将调用命令。CommandBuilding类实际上一共提供了四个事件:Execute、PreviewExecut、QueryEnabled和PreviewQueryEnabled
定义新命令,四个步骤可以很容易地定义命令
(1)声明一个静态命令对象: public static RoutedCommand myCmd;
(2)创建一个InputGestureCollection变量: static MainWindow(){ InputGestureCollection myInputs = new InputGestureCollection();
(3) 添加输入动作项目: myInputs.Add(new keyGesture(Key.G, ModifierKeys.Control | ModifierKeys.Shift));
(4)使用名称、类型和所创建的InputGestureCollection变量创建传递命令: myCmd = new RoutedCommand(“Go”, typeof(MainWindows), myInputs);
激活命令
一个命令类对象为应用程序提供了所有的命令执行功能。命令通过输入动作激活。WPF支持两种类型的输入动作,即MouseGesture和KeyGesture。因为使用命令类是静态的,所以可以将其作为一个可选的参数传递给控件作为执行上下文在这种方法中,可以通过调用它的Execute方法以编程的方式调用一个命令,
2.2.6 触发器
多种不同类型的可视化触发器:
- 属性触发器
- 事件触发器
- 数据触发器
- 多条件数据触发器
- 多触发器
- 多条件触发器
创建属性触发器的基本步骤如下。
小结
窗口、导航、事件、命令、样式、控件触发器以及本地化。
- 创建一个新的WPF应用程序,可以选XBAP、桌面项目、服务、导航或算卦民或自定义控件。
- 设计具有统一样式的友好用户界面和用户体验。
- 在XAML中创建交互控件元素,在XAML标记中直接镶嵌入触发器和其他响应机制。
- 处理控件级别的事件,包括嵌套控件的多级别事件(通过上传和下传事件)为所有控件和用户之间的交互提供重要的托管动作。
- 创建属性或数据触发器,在绑定或非绑定控件上处理上下文信息。
- 使用WPF对象模型,通过编程访问所有的窗口、控件和XAML页面上的保视化设计元素。