备注:内容来自于观看编程宝典
硬件加速:
1 User32:为许多元素(窗口,按钮,文本框)提供熟悉windows外形
2 GDI/GDI+:为渲染简单形状,文本和图形提供绘图支持。
WPF底层使用DirectX,优势:①可使用丰富的效果;②显卡硬件加速。
传统Windows应用程序的用户界面,即图像包含的像素数不变(精细程度不变),但图像大小会变。
WPF中,即图像大小不变,图像包含的像素数会变(精细程度会变)
dpi(dot per inch,每英寸像素点数)。[屏幕DPI] = √16002+12002像素 / 19英寸 =100 dpi
[物理单位尺寸] = [设备无关单位尺寸]×[系统DPI] = 1/96英寸×100dpi = 1.04像素
位图,用像素格的小点描述图像,缩放出现模糊。占用空间大。
矢量图,被定义为系列的形状(点、线、面)等构成,缩放清晰度不变。占用空间小
WPF中,最好使用矢量图。
WPF 体系结构
milcore 是以非托管代码编写的,实现与 DirectX 的紧密集成。性能敏感
注意:不管拖动,缩放,milcore负责绘制程序恰当部分。
WPF的类层次结构
总结:
当一个组件使用执行线程的标识来存储某种类型的状态时,将发生线程关联。
调度程序是一个基本的消息调度系统,具有多个按优先级排列的队列。
从 DispatcherObject 派生,获得指向调度程序的指针。
元素是可视化,控件是能交互
XAML是WPF设计UI的语言,设计师使用XAML设计界面,完成后输出XAML代码交给程序员使用。
命名空间:
为避免标签的名称冲突而出现,不同程序集中的类映射到自定义的命名空间前缀,使用语法xmlns[:可选的映射前缀]="名称空间和程序集"。没有映射前缀的命名空间为默认命名空间,默认命名空间只能有一个。命名空间映射一般写在根标签上。
标签与运行时对象的关系:
标签对应运行时中的一个对象,标签的包含关系也对应运行时中对象的包含关系。大多数标签的属性(Attribute)对应运行时对象的属性(Property)。
x: 前缀:用于映射 XAML xmlns http://schemas.microsoft.com/winfx/2006/xaml。
x:Class属性(Attribute):编译成C#代码后对应的类名,如果手动把该属性改成其他后台代码中不包含的类名称,编译后会自动生成该类。如果与后台代码的类名称相同则进行合并(后台代码中的类要用partial修饰)。
x:Key:为 ResourceDictionary 中的每个资源设置一个唯一的键。
x:Name:为运行时代码中存在的实例指定运行时对象名称。
x:Static:启用一个获取静态值的值引用,该静态值只能是一个 XAML 可设置属性。
x:Type:根据类型名称构造Type 引用。指定采用 Type 的属性
XAML的树形结构:XAML都是一个树,有唯一根节点,通常为Window或Page。提供VisualTreeHelper和LogicTreeHelper两个帮助类用来查找或操作树。
XAML对象属性赋值语法:
使用标签的Attribute语法通过字符串为对象属性进行简单赋值。如果系统中没有内置的转换时需要使用TypeConverter类将标签的Attribute与对象的Property进行映射。创建继承自TypeConverter的类并重写ConvertFrom方法并在需要应用该转换的类上应用TypeConverterAttribute属性。
属性元素语法,如果复杂属性无法通过简单字符串赋值时,可以通过使用属性元素语法为属性赋值。
标记扩展:
当需要为属性进行特殊类型的赋值时就需要使用标记扩展语法(如数据绑定或赋NULL值)。标记扩展语法:{Binding ElementName=Name1,Path=Value,Model=OneWay}。标记扩展是为属性赋值。从MarkupExtension派生的类才能使用标记扩展语法来创建对象。
注意:标记扩展是可以嵌套的,并且标记扩展类均已Extension作为后缀,在XAML使用时可以省略。
WPF嵌套元素:采用iLIST或Idictionary的add方法或什么
附加属性
可用于多个控件。 需要指定类型名.属性名,实际转化为方法调用。
事件:
除了使用Attribute语法给对象属性赋值外,还可以为对象(控件)关联事件。通过将事件处理函数的名称放到Attribute的值字符串中为事件指定处理器。
x:Code:
该标签可以将C#后置代码写到XAML文件中,代码内容一定要用xml语言的
引入程序集命名空间:
首先需要把程序集引入到项目中,然后使用xmlns语法,引用程序集中的类时,使用<映射名称:类名称>映射名称:类名称>语法引用。
语法:xmlns:prefix="clr-namespace:Namespace;assembly=AssemblyName"
prefix:是希望在XAML标记中用于指示命名空间的XML前缀。例如,XAML语言使用的x前缀。通常情况下,使用.net中其他的类型,前缀使用sys,而使用当前项目中的类型,前缀会使用local命名。
Namespace:是完全限定的.net命名空间的名称。
AssemblyName:是声明类型的程序集,没有.dll扩展名。这个程序集必须在项目中引用。如果希望使用项目程序集,则可以忽略这一部分。
注释:
语法,注释不能嵌套,并且只能出现在开始标签和结束标签之间。
WPF使用windows,page(可导航),application作为顶级元素。
可以创建不适用XAML的WPF
布局原则
放置多个元素,在窗体中布置一个容器添加别的元素。
原则:1 不显示设定尺寸 2不适用屏幕坐标指定位置。 3 子元素共享可用空间。
核心布局面板
容器修饰与封装
Grid面板支持以下三种设置尺寸的方式:
使用Row和Column附加属性在单元格中放置元素,附加属性RowSpan和ColumnSpan跨越多个单元格。
分隔条由GridSplitter类表示,通过添加GridSplitter对象,用户就可以改变行和列的尺寸。
Visibility的用法
属性
什么是依赖属性
依赖属性可支持WPF中的样式设置、数据绑定、继承、动画及默认值。
如何自定义依赖属性
1、声明依赖属性变量。通过public static来公开静态变量,类型必须是DependencyProperty
2、在属性系统中进行注册。使用DependencyProperty.Register方法来注册依赖属性,或者是使用DependencyProperty.RegisterReadOnly方法来注册
3、使用.NET属性包装依赖属性
特性
更改通知:当依赖项属性值被更改时,会得到通知,一般在绑定中使用。
属性值继承:某些依赖项属性可以从它的父元素中或元素树中的某个元素中得到。
依赖属性验证和强制功能
1、ValidateValueCallback:该回调函数可以接受或拒绝新值。该值可作为DependencyProperty.Register方法的一个参数。
2、CoerceValueCallback:该回调函数可将新值强制修改为可被接受的值。该回调函数PropertyMetadata构造函数参数进行传递。
理解:
路由事件是针对元素树中的多个侦听器的事件。
路由事件与一般事件的区别:路由事件触发后,它可以向上或向下遍历可视树和逻辑树,不需要定制代码
路由事件的路由策略
指:路由事件实现遍历元素的方式
一般情况下,WPF提供的输入事件都是以隧道/冒泡对实现的。隧道事件常常被称为Preview事件
路由事件编程
通过EventManager的RegisterRoutedEvent()函数向事件系统注册路由事件。
第一个参数name表示事件名称,而第二个参数routingStrategy则标明了路由事件的路由原则。第三个参数handlerType用来标明事件处理函数的类型,而最后一个参数ownerType则用来标明拥有该路由事件的类型。
AddHandler和RemoveHandler两个函数来给路由事件分配事件处理器。
三、共享路由事件
通过RoutedEvent的AddOwner()函数将其它类型所定义的路由事件作为自身的路由事件,RemoveOwner()移除
创建可以激发路由事件的方法
重写OnClick方法触发设定路由事件,使用RaiseEvent()触发
附加事件
以“类名.事件名”的方式使用不同的关联事件的语法,可以在代码中关联附加事件,但必须要用 AddHandler 而不是 +=。
处理挂起的事件:当事件的 Handle 属性被置为 true 意味着通知其它侦听对象此事件被处理过了,有一个方法用于接收被处理过的事件,它必须使用前面介绍过的 AddHandler 方法的一个重载版本,将第三个 bool 类型参数设置为 true
WPF事件:
生命周期事件:
a.Initialized 元素被实例化,但是窗口的其他部分可能还没有初始化。还没有应用样式和数据绑定。
b.Loaded 事件 ,应用了样式和数据绑定时,
c.Unloaded 当元素被释放时,窗口被关闭或特定的元素被从窗口中删除
FrameworkElement类实现了ISuppertInitialize接口,调用BeginInit()方法,XAML解析器设置所有元素的属性。调用EndInit(),引发Initalized事件。
包含其他所有元素的窗口首先引发Loaded事件,都引发了Loaded事件之后,窗口就变的可见了。
输入事件:通过外设如鼠标、键盘等进行输入操作时触发的事件。
焦点:为了让元素接收键盘输入,元素必须能够获得焦点。Focusable属性设置为true。
键盘状态:通过KeyboardDevice获取键盘状态
鼠标事件:鼠标操作会触发相关的事件。、捕获鼠标事件和鼠标拖放事件。
移入移出事件是MouseEnter和MouseLeave事件,这两个事件是直接事件
捕获鼠标事件:按下事件和释放事件是成对被触发的,但是也有另外,如单击某个元素,保持按下状态,然后移动鼠标指针离开该元素,这种情况就不会触发释放的事件。
鼠标离开元素,先判断该元素是否可用,通过CaptureMouse()方法来捕获鼠标
鼠标拖放事件:鼠标拖放是作为一种快捷方便的方式来使用的,例如将垃圾文件拖放到回收站,将一个doc文档拖放到打开的Word窗口来打开该doc文档等。
一般,拖放操作分为三个步骤:
重点是DragEventArgs对象的Data属性,它是IDataObject接口类型,用于封装拖放对象相关的信息,里面有一些经常要的方法,如GetData/SetData方法,GetDataPresent方法,一般使用DoDragDrop。
多点触控和手写笔不同的是,多点触控支持同时多个手指操作甚至手势(Gesture)
控件是可以和用户进行交互的元素
背景:指控件的表面,使用Background属性设置区域颜色;
前景:指文本,使用foreground设置区域颜色。
注:Background、Foreground属性并不是使用颜色对象,而是使用更强大的【Brush】对象。
Brush对象:该对象为填充前景和背景内容提供了灵活性,可使用单一颜色SolidColorBrush或者更特殊的颜色LinearGradientBrush(TitleBrush)填充背景和前景。
XAML中设置背景色和前景色:提供颜色名或者颜色值。
字体:
文本的装饰和排版:
通过TextDecoratons和Typography属性,。这些属性可以修饰文本,例设置TextDeorations属性,该类提供四种修饰,每种修饰都可以为文本添加几类线。包括BaseLine,OverLine、Strikethrough Underline。
字体继承: 设置任何字体属性是,属性值都会流经嵌套的对象。例如,如果为顶级窗口设置了FontFamily属性,窗口中的所有控件都会得到相同的FontFamily属性值(除非为控件明确设置了字体)
字体替换: 设置字体时,要确保字体在用户的计算机上已经存在,可以设置FontFamily的值逗号隔开,当前面的字体不存在时,使用后面待选字体
字体嵌入:使用:/#
文本格式化模式:小于15尺寸会模糊。
鼠标光标:使用Cursor类,wait是沙漏,ForceCursor属性,父元素会覆盖子元素的光标。
内容控件:能包含嵌套的元素。内容控件只能包含一个元素,而布局容器只要愿意可以包含任意多个嵌套元素。
Content属性:Panel类提供Children集合保存嵌套元素,Control类添加Content属性接受单一对象。属性支付对象:
对齐内容:通过使用HorizontalContentAlignment和VerticalContentAlignment属性属性内容控件中的内容如何和其边框对齐。
6.2.3 标签:标签具有记忆符,记忆符是能够为连接的控件设置焦点的快捷键。更轻量级的TextBlock元素。通过TextWrapping属性支持换行。
按钮:继承自ButtonBase类,添加了ClickMode属性,决定何时引发Click事件,ClickMode.Release(单击鼠标并释放时触发Click事件),ClickMode.Press是第一次按下时引发,ClickMode.Hover是在按钮上悬停一会儿就触发。
Button控件——Windows下压按钮。
CheckBox控件:继承自ToggleButton,有"开关"行为。IsChecked:true、false、null。null表示不确定的状态,带有阴影的复选框。
RadioButton:继承自ToggleButton类。增加了GroupName属性,用于控制如何对单选按钮进行分组。单选按钮通常由它们的容器就行分组。
工具提示:为元素简单的设置Tooltip属性,ToolTip属性是在FrameworkElement类中定义的,所以所有可以放置到窗口上的元素都可以使用ToolTip属性。内存存储在Content
ToolTipService属性——有几个工具提示属性不能通过ToolTip类的属性配置。使用ToolTipService类可以配置显示工具提示的相关延迟时间。
Popup控件——包含单一内容的任何WPF元素。使用IsOpen显示或隐藏。内容存储在Popup.Child中。
ScrollViewer控件——让大量的内容适应有限的空间,滚动是一个重要特性。
自定义滚动——允许所包含的内容参与滚动过程。
GroupBox显示为一个具有圆角和标题的方框。
TabItem表示TabControl控件的一页。IsSelected指示是否正显示在TabControl控件中
Expander控件:他包装了一块内容单击小箭头可以显示或隐藏。开始都是折叠的,设置IsExpanded属性改变。
文本控件:TextBox存储字符串。PasswordBox处理字符串(Password提供),内部使用SecureString。只有RichTextBox控件存储更复杂:FlowDocument。
多行文本:TextBox将TextWrapping设置为Wrap,控件的边缘换行,为WrapWithOverflow,允许拉伸。
选择文本:TextBox类还提供SelectionStart标识所选文本的开始位置,SelectionLength指示选中的字符数量。SelectedText属性快速检查或改变选中的文本。
6.5.3 拼写检查:设置TextBox的SpellCheck.IsEnabled
6.5.4 PasswordBox:圆圈符号屏蔽实际字符。不能复制文本。password读取。变化时触发事件PasswordChanged
ListBox——允许用户从长度可变的列表中选择一项。可嵌套ListBoxItem。也可以嵌套其他元素,ListBoxItem能包含嵌套的内容。够隐式的创建所需的ListBoxItem对象。
ComboBox使用下拉列表,一次只能选一个项目。ComboBoxItem也可以包含任何元素。输入文本将IsEditable设置为true,确保存储的纯文本的或者提供ToString()。
基于范围的控件:使用在特定最小值和最大值之间的数值。ScrollBar、 ProgressBar以及Slider都继承自RangeBase类
Slider控件 ,当数字本身不是特别重要时使用。比如播放器的音量调节。以刻度显示。
6.7.2 进度条:用于指示长时间运行任务的进度。不能和用户进行交互。需要由代码递增Value属性值。
日期控件:Calendar和DatePicker。都允许用户选择一个日期。Calendar显示日历,DatePicker提供了下拉箭头。选中值改变事件SelectedDateChanged。
启动创建应用程序对象,有各种事件,可以监听某些事件,释放对象程序结束。
WPF存在Application实例,接收程序参数,处理程序事件。
创建Application对象:
不使用wpf:应用程序中,启动main方法,实例化application类,向application类中传递界面实例。 (Run方法)
经典的WPF应用程序启动实例:
采用了app.xaml来配置应用程序,制造派生类App,派生于Application类。Main方法让WPF框架给藏起来了。
xaml是类模板,VS利用XAML自动生成C#类App.g.cs。
StartupUri指定应用程序启动的主界面。可以自定义语句处理接收到的命令行参数和应用程序事件处理代码。Startup属性指定启动类。
关闭是有ShutdownMode属性设置:
窗口未关闭,保持应用程序处于有效状态,可调整Application.ShutdownMode属性。
应用程序事件:
使用:在xmal指定事件。重写父类方法,事件名称加On
4、显示初始界面。
第一次启动初始化 .Net环境,需要显示初始界面
步骤:1.添加文件;2.选择文件;3.属性窗口将生成操作改为 SplashScreen;
代码:1 new SplashScreen("1.png"); 2 Show() 3 Close()
命令行参数:需要相应Application.Startup事件。StartupEventArgs.Args属性作为字符串数组提供的。
访问当前Application对象:通过Application.Current属性可在应用程序的任何位置获取当前应用程序实例。
主窗口:Application.Current.MainWindow
6、窗口之间进行交互步骤。
7、单实例应用程序。
程序集资源:作为不透明的二进制数据嵌入到已编译程序集,XAML会被编译为BAML,图片等其他资源均被编译到程序集中AssemblyResources.g.resources中。
添加资源:在属性窗口,将build action改为resource
检索资源: 1 Application.GetResourceStream(uri);2 XAML中引用