七月 15

wpf之文本控件

TextBox:文本框控件

存储字符串格式的文本

MaxLength:文本框控件最多可以输入的字符长度

TextWrapping:自动换行属性。如果想要自动换行,则设置为Wrap

VerticalScrollBarVisibility:纵向滚动条设置。设置为Auto则自动调整

SelectionStart:选中文本的开始位置

SelectionLength:选中文本的长度

SelectedText:选中的文本

SpellCheck.IsEnabled:拼写检查,设置为True则开启拼写检查。目前这个功能不能检查中文。检查英文时也要求键盘设置为英文键盘。

LineUp()方法:向上一行。还有类似的LineDown()、PageUp()、PageDown()、ScrollToHome()、ScrollToEnd()等方法。

PasswordBox:密码框控件

通过显示实心点等方式来屏蔽实际输入的字符串。密码框控件不能复制粘贴。

PasswordChar:设置加密的字符。在密码框中输入的所有字符都将以设置的字符形式显示。

七月 12

wpf之带标题的内容控件

GroupBox

GroupBox就是带有圆角和标题的方框。

Header:标题。如果想在Header中添加多种元素,那么就需要设置成属性元素。

Content:内容,通常用属性元素形式来设置。由于带标题的内容控件也是继承自内容控件,因此Content中只能有一个元素。如果想要多个元素,需要先放置一个布局元素,然后再在布局元素中添加多个元素。

TabItem

TabItem是TabControl中的一页内容。

Header:标题。如果想在Header中添加多种元素,那么就需要设置成属性元素。

Content:内容,通常用属性元素形式来设置。由于带标题的内容控件也是继承自内容控件,因此Content中只能有一个元素。如果想要多个元素,需要先放置一个布局元素,然后再在布局元素中添加多个元素。

TabStripPlacement:Tab的放置位置。可以放置在上下左右四个位置。

选择哪个TabItem可以在C#代码中通过 this.TabItem1.IsSelected属性进行设置。

Expander

通过一个小箭头来显示或者隐藏某些内容。

Header:标题。如果想在Header中添加多种元素,那么就需要设置成属性元素。

Content:内容,通常用属性元素形式来设置。由于带标题的内容控件也是继承自内容控件,因此Content中只能有一个元素。如果想要多个元素,需要先放置一个布局元素,然后再在布局元素中添加多个元素。

ExpandDirection:展开方向。

七月 10

正则表达式 – 元字符

字符描述
\将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,’n’ 匹配字符 “n”。’\n’ 匹配一个换行符。序列 ‘\\’ 匹配 “\” 而 “\(” 则匹配 “(“。
^匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。
$匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。
*匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。
+匹配前面的子表达式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。
?匹配前面的子表达式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does” 。? 等价于 {0,1}。
{n}n 是一个非负整数。匹配确定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。
{n,}n 是一个非负整数。至少匹配n 次。例如,’o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等价于 ‘o+’。’o{0,}’ 则等价于 ‘o*’。
{n,m}m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,”o{1,3}” 将匹配 “fooooood” 中的前三个 o。’o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。
?当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,’o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’。
.匹配除换行符(\n、\r)之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用像”(.|\n)”的模式。
(pattern)匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 ‘\(‘ 或 ‘\)’。
(?:pattern)匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, ‘industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。
(?=pattern)正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,”Windows(?=95|98|NT|2000)”能匹配”Windows2000″中的”Windows”,但不能匹配”Windows3.1″中的”Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern)正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如”Windows(?!95|98|NT|2000)”能匹配”Windows3.1″中的”Windows”,但不能匹配”Windows2000″中的”Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?<=pattern)反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如,”(?<=95|98|NT|2000)Windows”能匹配”2000Windows”中的”Windows”,但不能匹配”3.1Windows”中的”Windows”。
(?<!pattern)反向否定预查,与正向否定预查类似,只是方向相反。例如” (?<!95|98|NT|2000)Windows “能匹配” 3.1Windows “中的” Windows “,但不能匹配” 2000Windows “中的” Windows “。
x|y匹配 x 或 y。例如,’z|food’ 能匹配 “z” 或 “food”。'(z|f)ood’ 则匹配 “zood” 或 “food”。
[xyz]字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。
[^xyz]负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’、’l’、’i’、’n’。
[a-z]字符范围。匹配指定范围内的任意字符。例如,'[a-z]’ 可以匹配 ‘a’ 到 ‘z’ 范围内的任意小写字母字符。
[^a-z]负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]’ 可以匹配任何不在 ‘a’ 到 ‘z’ 范围内的任意字符。
\b匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
\B匹配非单词边界。’er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
\cx匹配由 x 指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。
\d匹配一个数字字符。等价于 [0-9]。
\D匹配一个非数字字符。等价于 [^0-9]。
\f匹配一个换页符。等价于 \x0c 和 \cL。
\n匹配一个换行符。等价于 \x0a 和 \cJ。
\r匹配一个回车符。等价于 \x0d 和 \cM。
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t匹配一个制表符。等价于 \x09 和 \cI。
\v匹配一个垂直制表符。等价于 \x0b 和 \cK。
\w匹配字母、数字、下划线。等价于'[A-Za-z0-9_]’。
\W匹配非字母、数字、下划线。等价于 ‘[^A-Za-z0-9_]’。
\xn匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,’\x41′ 匹配 “A”。’\x041′ 则等价于 ‘\x04’ & “1”。正则表达式中可以使用 ASCII 编码。
\num匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)\1′ 匹配两个连续的相同字符。
\n标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
\nm标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。
\nml如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。
\un匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。
七月 9

wpf之内容控件

内容控件简介

wpf中的内容控件是一种特殊的控件类型。它可以包含并且显示一块内容。从技术的角度讲,内容控件是可以嵌套单个元素的控件。这一点与可以嵌套多个元素的布局控件不同。 所有的内容控件都是继承自ContentControl类。常见的Label以及Button控件都是内容控件。

Content属性

内容控件都包含Content属性。Content属性只能设置为一个元素,虽然元素的类型可以是多种多样的。Content不仅仅可以是字符串,还可以是图片等。那么如果想要同时在Content中显示图片和字符串怎么办呢?答案很简单,我们可以在Content属性中设置一个布局容器,然后再在布局容器中添加多个元素就可以了。

如果要设置Content的对齐方式,可以使用HorizontalContentAlignment或者VerticalContentAlignment。

Label控件(标签控件)

在所有控件中,最简单的就是Label控件(标签控件)。由于Label标签控件常常用来说明其他控件,因此它和它所说明的控件往往是可以绑定在一起的。这种绑定用的是Target属性。

Target = "{Binding ElementName=textBox1}"

设置快捷键需要使用_,而不是之前winForm中的&。所有设置的快捷键都默认和alt一起使用。

Button控件(按钮控件)

wpf中提供了三种Button按钮控件。包括我们熟悉的Button控件,还有CheckBox(复选框)控件以及RadioButton(单选钮)控件。

当我们设置IsCancel为True的时候,当我们在键盘上按ESC的时候,就会触发这个按键的Click事件。

当我们设置IsDefault属性为True的时候,当我们鼠标没有指向任何按钮时,按下回车键就会触发IsDefault设置为True的按钮。

CheckBox控件包含一个叫做IsChecked的属性。这个属性有三种选择,除了True和False,还有一个为{x:Null}, 表示未确定。如果需要可以选择 {x:Null} 状态,我们需要将IsThreeState设置为True。

RadioButton在一个布局容器中有多个可以RadioButton,但是我们只能从中选择一个。如果不在同一个容器下的RadioButton想要有互斥的效果,那么我们需要给不同容器下的RadioButton设置相同的GroupName属性。

ToolTip控件( 工具提示 )

我们可以为元素添加ToolTip工具提示属性。工具提示中可以放置任何需要的可视化元素。比较复杂的ToolTip需要设置为元素属性,例如Button.ToolTip。如果需要设置工具提示的背景色以及放置位置,那么可以在Button.ToolTip中添加ToolTip元素并且设置BackGround,Placement,HorzontalOffset以及VerticalOffset等属性。

七月 8

wpf之控件类

控件类(Control)简介

wpf中充满了各种元素,但是这些元素中只有一部分是控件。wpf中的控件指的是那些和用户交互的元素。也就是那些能够接受焦点并接受用户输入的元素。例如文本框,按钮等。所有的控件都继承自Control类。

背景画刷和前景画刷

所有的控件都包括背景和前景。背景是指控件的表面,而前景则是指控件上的文字。背景和前景用的都是Brush对象。示例:

this.button1.Background = new SolidColorBrush(Colors.AliceBlue);
this.button1.Background = new SolidColorBrush(Colors.FromRgb(255, 0, 0));

还可以赋予系统自带的颜色。示例:

this.button1.Background = System.Windows.SystemColors.ControlDarkBrush;

也可以使用RGB值来进行设置。示例:

字体属性

FontFamily:选择字体

FontSize:字体大小

FontStyle:字体样式

FontWeight:文本的粗细

FontStrech:问题的拉伸或压缩

TextDecoration:字体装饰。有BaseLIne,StrikeThrough,UnderLine,OverLine。

示例:加载计算机上拥有的所有字体

foreach (FontFamily fontFamily in Fonts.SystemFontFamilies)
{
    this.listBox1.Items.Add(fontFamily.Source)
}

字体继承:一旦我们在某个元素中设置了字体,那么默认的包含在其中的元素也使用相同的字体,除非被包含的元素自己指定字体。

对于小尺寸的文字,可能会出现模糊的问题。此时可以在XAML中设置

TextOptions.TextFormattingMode = "Display"

对于大尺寸文字则不需要如此设置。

鼠标光标

Windows中自带许多类型的光标,例如常见的箭头,等待时的沙漏,还有帮助菜单中的问号。我们可以在C#和XAML中设置光标的形状。代码示例:

C#: this.Cursor = Cursors.Wait
XAML: Cursor = "Help"
七月 8

wpf之理解鼠标输入事件

MouseEnter事件:当鼠标移动到某个元素上时,就触发MouseEnter事件。需要注意的是,这是一个直接事件。

MouseLeave事件:当鼠标指针离开某个元素时,就触发MouseLeave事件。这个事件也是一个直接事件。

PreviewMouseMove事件:移动鼠标时就会触发这个隧道事件。事件会提供一个MouseEventArgs对象。这个对象包含鼠标此时状态的一些属性,还有一个叫做GetPosition()的方法可以获得鼠标的坐标。GetPosition()方法中的参数为坐标所在的坐标系,一般情况下用this即可。GetPosition()返回的为一个类型为Point数据。因此,使用GetPosition()方法的一个案例为:

Point pt = e.GetPosition(this);

MouseMove事件:与PreviewMouseMove对应的冒泡事件。

鼠标单击事件

PreviewMouseLeftButtonDown以及PreviewMouseRightButtonDown事件:按下鼠标时触发的隧道事件。

MouseLeftButtonDown以及MouseRightButtonDown事件:按下鼠标时触发的冒泡事件。

PreviewMouseLeftButtonUp以及PreviewMouseRightButtonUp事件:释放鼠标时触发的隧道事件。

MouseLeftButtonUp以及MouseRightButtonUp事件:释放鼠标时触发的隧道事件。

这些鼠标单击事件都会提供一个MouseButtonEventArgs的对象。值得注意的是,Windows程序一般是对Up类事件进行相应,而不是对Down事件进行相应。

鼠标捕获事件

绝大多数时候,在一个鼠标按键按下的动作之后,紧接着会有一个鼠标按键释放的动作。然而,在有的时候也并非如此。例如,我们可能在按下鼠标按键之后先把鼠标移动出这个点击的元素再释放。这样,接收鼠标按下动作的元素就无法接收鼠标释放的动作了。如果我们希望这个元素仍然能够接收鼠标释放的动作,就需要使用鼠标捕获事件,让这个元素捕获鼠标。这样,无论鼠标在按下后移动到哪里,这个元素都可以接收到鼠标释放的动作。需要注意的是,一旦鼠标被某一个元素捕获之后,其他的元素就无法接收鼠标的信息了。

示例:Mouse.Capture(this.button1); //让button1捕获鼠标。

鼠标拖放事件

鼠标拖放事件一般首先在拖拽源的MouseDown函数中定义:

DragDrop.DoDragDrop(dragSource, dragContent, DragDropEffects.(对应的枚举))

接收拖拽的元素首先要在XAML中设定AllowDrop为True。这样才能接收拖拽过来的数据。然后,要在接收拖拽的元素上添加Drop事件,并进行设置:

((将Object转化为的类型)sender).Content = e.Data.GetData(DataFormats.Text);

温馨提示:TextBox自带拖放功能。

七月 7

wpf之理解键盘输入事件

wpf的事件类型

在wpf中,最重要的事件类型有五种:生命周期事件,鼠标事件,键盘事件,手写笔事件以及多点触控事件。生命周期事件是在元素被初始化加载或者卸载的时候发生的事件。而剩下的四种事件则都是输入事件,也就是说,由用户对操作系统进行输入是发生的事件。

wpf中的键盘输入

当用户按下键盘上的按键时,最先触发的是PreviewKeyDown事件。通过前面的学习我们知道,所有带有Preview的事件都是隧道路由事件,这一个也不例外。.

随后触发的事件是KeyDown事件。这个这也是一个路由事件,只不过是一个冒泡路由事件,而不是一个隧道路由事件而已。

接下来触发的事件是PreviewTextInput。这个事件在按键过程已经完成,元素正在接受文本输入的时候发生。对于不能产生文本输入的按键,例如Ctrl,Shift等,并不能触发这个事件。

再之后是TextInput事件。和前面介绍的PreviewTextInput一样,它也只能由产生文本输入的按键触发。

接下来是PreviewKeyUp。从名字中我们就可以知道,这个事件是在释放按键的时候触发的。

最后是KeyUp。这个是在释放按键的时候触发的事件。

七月 6

wpf之如何理解路由事件(Routed Event)

初学者看到路由事件这个名字的时候都会不禁好奇:这个路由指的是什么?和我们家里平时用的路由器有关系吗?

事实上,无论是我们家里用的路由器,还是路由事件,名字中的路由的概念是一样的,他们都表示起点与终点间有若干个中转站,从起点出发后经过每个中转站时要做出选择,最终以正确(比如最短或者最快)的路径到达终点。

作为程序员来说,我们编程的本质是通过编译我们所写的代码来扩展操作系统的功能,所以,程序的基本运行不可能脱离操作系统。要正确理解路由事件首先需要正确理解wpf所依赖的操作系统,Windows操作系统。

Windows操作系统本身就是一种消息驱动的操作系统,所以我们的程序注定都是消息驱动的,程序运行的时候也要把合己的消息系统与整个操作系统的消息系统“连通”才能够被执行和响应。

纵观几代 Windows 平各理序开发,最早的windowsAPI开发(C语言)和MFC开发我们可以直接看到各种消息并可以定义自己的消息。到了COM和VB时代,消息被封装为事件(Event)并一直沿用至.NET平台开发。

无论怎么说,程序间模块使用消息互相通信的本质是没有改变的。从Windows API开发到传统的.NET开发,消息的传递(或者说事件的激发与响应)都是直接模式的,即消息直接由发送者交给接收者(或者说事件宿主发生的事件直接由事件响应者的事件处理器来处理)。WPF把这种直接消息模型升级为可传递的消息模型。

前面我们已经知道WPF的UI是由布局组件和控件构成的树形结构,当这棵树上的某个结点激发出某个事件时,程序员可以选择以传统的直接事件模式让响应者来响应之,也可以让这个事件在UI组件树沿着一定的方向传递且路过多个中转结点,并在这个路由过程中被恰当地处理。你可以把WPF的路由事件看成是一只小蚂蚁,它可以从树的基部向顶部(或反向)目标爬行,每路过一个树枝的分又点就会把消息带给这个分叉点。

关于wpf中的路由事件就给大家介绍到这里。希望通过我的简单描述,大家能够更加直观的理解wpf中的路由事件。

七月 6

C#中Enum .GetValues (typeof(EnumName ))为什么要加typeof

当我们需要获取某个枚举类型中的所有值时,就需要用到Enum.GetValues方法。一个常见的错误就是直接把枚举的名称当做参数来使用,例如下面的代码:

Enum .GetValues (EnumName);

然而这并不是正确的做法。正确的做法是,还需要在参数中加一个typeof()运算符。你没看错,我也没有写错,typeof()是一个运算符,不是一个方法。正确的写法如下:

也就是Enum .GetValues(typeof(EnumName));

安静本人比较喜欢刨根问底,因此就很好奇为什么要多此一举的加上typeof运算符呢?于是我找了很多的中英文的文档,最终也么找到,大家绝大多数用下面的解释:

GetValues()方法的参数信息显示是这样的:

public static Array GetValues( Type enumType )

要求参数是enumType的类型为Type,而不是Enum。因此在我们要使用typeof获取Enum的类型。

这个方法只是解释了表象,最终还是没能解释深层次的原因。如果有哪位大神碰巧知道,欢迎留言赐教。

七月 5

wpf笔记之xmal里面的Name和x:Name有什么区别

经常会有初学者问:在XAML代码中是应该使用Name呢,还是x:Name?

Name属性定义在FrameworkElement类中,这个类是WPF控件的基类,所以所有WPF控件都具有Name这个属性。当一个元素具有Name属性时,你使用Name或x:Name效果是一样的。比如<Buton x:Name=”btn”/>和<Buton Name=”btn”/>,XAML编译器的动作都是声明名为btn的Button类型变量并引用一个Button 类型实例,而且此实例的Name属性值亦为btn。此时,Name和x:Name是可以互换的,只是不能同时出现在一个元素中。

对于那些没有Name属性的元素,为了在XAML声明时也创建引用变量以便在C#代码中访问,我们就只能使用x:Name。有的编程者认为,因为x:Name的功能涵盖了Name属性的功能,所以全部使用x:Name以增强代码的统一性和可读性。但是安静还是认为,由于绝大多数代码都可以直接使用Name,那么和何乐而不为呢?只是在不能是用Name的时候,使用x:Name就好了。