【译】Teach Yourself WPF in 24 Hours(Hour 3)
最近由于项目需要开始学习传说中的WPF,呃,春哥好像有点生我的气了,当我用神器Google找学习资料的时候找了好久都没有找到。后来在电脑上发现了一个不知道什么时候下载下来的关于WPF的书,也就是我准备译的这一本了。
译此书有两个目的:一、主要是学习WPF,完成项目
二、鸟文好久没有动过了,不知道还能不能玩得动,这里温习一下
由于不是资深鸟文专家,而且WPF也是新手,译得不对之处大家多多指正。 呃,废话就到这里,Let‘s Rock .
呃,还有点废话,本书前面的二个小时就是对WPF的一些介绍,我就不费神去译了,直接上第三小时实战。
第三小时 Font Viewer 介绍
(其实就是做一个Font Viewer 字体查看器)
在这个小时中你将学到什么:
Ø 怎么建立一个新的WPF工程
Ø VS的一些基本知识
Ø 一个WPF工程的结构
Ø XAML文件
Ø 后台代码文件
在这个小时的课程中我们将打造第一个WPF应用程序——一个用来查看你的系统当前安装的所有字体的辅助工具。我们也将学会如何在Visual Studio 中建立一个简单的WPF工程。
建立Font Viewer
让我们谈谈我们将建立的应用程序开始本节课程吧。
拥有一个轻量级的可以查看你当前系统所安装的字体的辅助工具将是一件很方便的事情。另外,我们还可以输入一些样本文字来看看他在当前字体下的效果。
为了完成这个辅助工具我们需要:
Ø 一个ListBox来显示当前系统安装的所有字体
Ø 一个TextBox来输入示例文字
Ø 一个可以用当前选中的字体演示样例文字的地方
在Visual Studio 2008 中建立新的工程
我们将在Microsoft Visual C# 2008 Express Edition (见图3.1)中进行开发。 这是一个同.Net3.5一起发布的特别版的Visual Studio。它本身就支持WPF程序的开发。如果你拥有的是其它版本的VS2008 ,也是可行的,当然你的步骤和本书也许会有一点点的区别。
下面是建立一个WPF工程的步骤:
1. 打开Visual Studio 。它在你的开始菜单中。
2. 在菜单栏中选择 文件——新工程。
3. 选择WPF应用程序模板,如图3.2所示
4. 把你的应用程序命名为FontViewer然后单击确定
(怎么感觉作者把读者当白痴了,呃。。。学WPF的人应该都有这些基础的吧)
![]() | |||
![]() |
图3.1 Microsoft Visual C# 2008 Express Edition
图片3.2 建立一个新的WPF应用程序
基本的工程文件
VS会自动的创建App.xaml,Window1.xaml以及和Window1.xaml相关联的后台代码文件,然后Window1.xaml会显示在你的IDE中。
XAML文件只包涵一些我们在“第二小时——理解XAML ”中讨论过的标记。后台代码文件包涵一些额外的与XAML关联的代码(在本例中是C#代码)。
App.xaml代表的是应用程序本身。它不是可视化的,主要用来保存整个应用程序要用到的资源。App.xaml同时还定义了应用程序加载时打开哪个窗体。
Window1.xaml是整个程序的主窗体。它里面的标记包涵了应用程序中所有的可视元素同时还声明了程序的行为。
什么是后台代码?
在WPF应用程序中,每个XAML文件都有一个与之对应的的后台代码文件。后台代码文件和他的父文件同名并以.cs或.vb做为后缀名。因此Window1.xaml的后台代码文件就是Window1.xaml.cs。
在解决方案浏览器中,后台代码文件是它所关联的文件的孩子(树形结构显示)。它们嵌套在其父文件的下面。
你可以在代码编辑器中单击右键选择“查看代码”或者“视图设计器”分别在标记语言和代码之间切换。注意,VS将会为XAML和后台代码各打开一个标签。
分离你的关注点
使用后台代码文件的用意是让开发人员把UI渲染开发和程序行为的开发分离开来,注重到各自的开发工作上去。WPF在这方面的实践上比Windows Forms 和ASP.NET Web Forms都做得好,尽管这使我们很容易把这些东西混淆。(原句:Although it is still very easy to muddy the waters.不知道怎么翻了,呃。)
例如,假设一个有两个人的团队正在开发一个WPF应用程序,其中一个是美工另一个是码工(呵呵,这样译出了我的心声——都是民工)。码工想实现一个允许用户在一个ListBox中选取他最喜欢的颜色的功能。美工想要用一个调色板来展示用户在ListBox中所选择的颜色。这种情况下,美工可以编辑XAML文件以创建一个别致的ListBox而不用去改变任何码工所写好的代码,同时也不会破坏整个应用程序。
这仅仅是把UI设计和行为逻辑编写分开的好处的冰山一角。在本书中我们还将更多的讨论这个概念和这么做的好处。
重命名XAML文件
我们刚刚创建的Font Viewer 应用程序现在在VS中打开了。如果我们按F5键,就会看见一个可以运行但是没有任何用处的WPF应用程序。
VS默认提供的文件名并没有多大的意义。根据其用途来命名文件、类、方法是一个很好的习惯。所以我们将要重命名Window1.xaml来表明它是整个程序的主窗体。
如果不小心的话,重命名VS中的项将会破坏整个应用程序。为了保证重命名窗体时文件间的关联正确,我们需要这样做:
1. 在解决方案浏览器中选择Window1.xaml.
2. 按F2(同样的,你也可以右键选择重命名)。
3. 重命名Window1.xaml为MainWindow.xaml,这时我们会注意到VS自动的把与之关联的后台代码文件也重命名了。但是,VS并没有正确的重新引用新的文件名,也没有改变内部类的名字。
4. 在解决方案管理器中双击App.xaml以在编辑器中打开它。
5. App.xaml的根标签是 Application 标签,Application标签有一个名为StartUpUri的属性。StartUpUri属性指定了应用程序运行时显示的主窗体。我们可以看见它还指向了旧的文件名Window1.xaml。现在我们把它改来指向MainWindow.xaml,修改后的App.xaml看起来应该是这样的:
<Application x:Class="FontViewer.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
6. 在代码编辑器中打开MainWindow.xaml的后台代码即MainWindow.xaml.cs。我们注意到类仍然为Window1,重命名XAML文件并没有改变类名。
7. 为了避免混淆,我们把类名改为和文件名相匹配。右击类名,选择重构——重命名,输入MainWindow做为新的类名,单击确定然后单击应用。你也可以在菜单样中选择重构——重命名如图3.3所示。
我们也会注意到VS并没有把类前的注释里的类名更正,所以我们把注释里的类名也改过来——保证注释与你的代码同步更新是一个很好的习惯。
8. 最后,在MainWindow.xaml文件的标记中,我们还需要把引用的类改为正确的类。标记语言的根标签是 Window,它拥有一个属性x:Class。我们要把这个属性改为类的全名——包括命名空间,FontViewer.MainWindow.MainWindow.xaml。更正后MainWindow.xaml看起来应该是这样的:
<Window x:Class="FontViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Font Viewer"
Height="300"
Width="300">
<Grid>
</Grid>
</Window>
![]() |
图3.3在菜单栏中选择重构
开发这个应用程序
在本小时课程的开始我们说过我们要做什么了——用我们的应用程序来显示当前系统所安
装的所有字体列表。我们还想让程序拥有这样的功能:在一个列表中选择某个字体,然后在文本框中输入一些示例文字看看这些文字在该字体下的效果。
让一个程序更容易使用也是十分重要的,所以我们还将在程序中加入一些有用的提示性文字以及间隔来提升程序的可用性。
现在,让我们开始加入这些特性吧:
1. 在代码编辑器中打开MainWindow.xaml。默认情况下VS会用一个分割窗体显示XAML文件。窗体中的设计视图窗格会几乎实时的显示XAML文件的预览效果,而XAML窗格则用来显示标记语言本身。
2. 首先,让我们给应用程序命以一个有意义的名字,它将会显示在应用程序的标题栏中。更改Window标签的Title属性为Font Viewer。
3. 窗体的默认大小有些过小了。我们可以通过Window标签的Height和Width属性来改变窗体的大小。设置Height为480,Width为600。(单位px)
4. 现在定位到Grid标签。Grid控件是允许你可视化的安排UI元素的控件之一。这些用于布局的控件被称为面板——我们将在第四小时的课程“掌握应用程序布局”中详细的讨论它们。删除Grid标签。
5. 在刚才删除了Grid的地方输入<DockPanel。智能感知功能这时会出现,你可以简单的从出现的列表中选择DockPanel。(记住,在使用智能感知功能来输入XAML标签时要用<符号开始该标签。DockPanel是另外一个类似Grid的用来布局UI元素的面板控件。DockPanel在布局类似VS和Microsoft Outlook这样的应用程序时十分有用——它们当中的大部分UI元素都停靠在主窗体的边缘上。更改后的XAML应该是这样的:
<Window x:Class="FontViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Font Viewer" Height="480" Width="600">
<DockPanel></DockPanel>
</Window>
6. 在DockPanel内输入以下代码:
<Border DockPanel.Dock="Top"
CornerRadius="6"
BorderThickness="1"
BorderBrush="Gray"
Background="LightGray"
Padding="8"
Margin="0 0 0 8">
</Border>
在设计视图中可以看到应用程序的主窗体现在已经包涵了一个浅灰色的拥有圆角的矩形。在编辑XAML文件时记住不时的看看设计视图,这样你会更好的理解你正在输入的标记——它们都实时的展现在了设计窗体中。
7. 给你的用户一些引导总是十分有用的。所以,让我们加入一些说明性的文字吧。在新加入的Border内部输入以下内容:
<TextBlock FontSize="14"
TextWrapping="Wrap">
Select a font to view from the list below.
You can change the text by typing in the region at the bottom.
</TextBlock>
8. 现在我们将会向窗体中加入一个显示系统当前安装的所有字体的ListBox。在Border标签的后面(但仍然在DockPanel标签内部),加入以下内容:
<ListBox x:Name="FontList"
DockPanel.Dock="Left"
ItemsSource="{x:Static Fonts.SystemFontFamilies}"
Width="160" />
其中的ItemsSource属性用来告诉ListBox它将要显示的数据源。在本例中我们想要显示的数据即当前系统所安装的所有字体。.NET Framework 中的类 System.Windows.Media.Fonts为我们提供了一个静态的属性SystemFontFamilies。默认情况下ListBox会调用SystemFontFamilies集合中的每个FontFamily实例的ToString方法。幸运的是,这个方法返回的正是FontFamily的名字。
在接下来的课程中我们还会更深入的讨论关于这些的细节。
完成以上步骤后MainWindow.xaml里的标记语言应该是这样的:
<Window x:Class="FontViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Font Viewer" Height="480" Width="600">
<DockPanel>
<Border DockPanel.Dock="Top" CornerRadius="6" BorderThickness="1"
BorderBrush="Gray" Background="LightGray" Padding="8" Margin="0 0 0 8">
<TextBlock FontSize="14" TextWrapping="Wrap">
Select a font to view from the list below.
You can change the text by typing in the region at the bottom.
</TextBlock>
</Border>
<ListBox x:Name="FontList" DockPanel.Dock="Left" ItemsSource="{x:Static Fonts.SystemFontFamilies}" Width="160" />
</DockPanel>
</Window>
9. 现在我们需要一些可以输入样例文字和用当前选中的字体来预览该文字的方法。
在ListBox下面加入下面这些标签:
<TextBox x:Name="SampleText" DockPanel.Dock="Bottom" MinLines="4" Margin="8 0" TextWrapping="Wrap" ToolTip="Type here to change the preview text.">
The quick brown fox jumps over the lazy dog.
</TextBox>
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" TextWrapping="Wrap" Margin="0 0 0 4" />
TextBox接受用户的输入,同时我们还提供了一些默认的文字。TextBlock是一个用来显示文本的元素。
我们注意到,TextBlock的Text属性绑定到了TextBox(我们命名为SampleText)的Text属性上。这将告诉WPF保持这两个属性同步——无论什么时候用户在TextBox中输入文字TextBlock都会自动的更新以保持与TextBox里的内容相同。
10. 最后,运行你的程序吧。当然,你也可以对程序稍做修改以体验WPF的更多魅力。
完善一些细节
在玩弄现在的Font Viewer一会儿后你不难发现用多种不同大小的字体来显示样例文字将会使程序更有用。让我们加入一些标签分别以10pt,16pt,24pt和32pt的大小显示样例文字吧。
我们会做以下修改来在四个不同的地方以不同的大小显示样例文字。
1. 用以下标记语言来代替绑定到了SampleText的TextBlock:
<StackPanel Margin="8 0 8 8">
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="10" TextWrapping="Wrap" Margin="0 0 0 4" />
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="16" TextWrapping="Wrap" Margin="0 0 0 4" />
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="24" TextWrapping="Wrap" Margin="0 0 0 4" />
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="32" TextWrapping="Wrap" />
</StackPanel>
这将在程序中加入一个StackPanel——另外一种布局控件。StackPanel控件会把他的子元素一个一个的堆叠起来,在本例中它的子元素是四个不同字体大小的TextBolck元素。
我们注意到,四个TextBolck都绑定到了同一个数据源——名为SqmpleText的TextBox的Text属性。
2. 给DockPanel加上一个8像素大小的外边距。这样使得用户界面看起来不那么拥挤同时也提升了程序的易用性:
<DockPanel Margin=" 8">
完成后的MainWindow.xaml看起来应该同代码清单3.1相似。
代码清单3.1 MainWindow.xaml
<Window x:Class="FontViewer.MainWindow2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Font Viewer" Height="480" Width="640">
<DockPanel Margin="8">
<Border DockPanel.Dock="Top" CornerRadius="6" BorderThickness="1" BorderBrush="Gray" Background="LightGray" Padding="8" Margin="0 0 0 8">
<TextBlock FontSize="14" TextWrapping="Wrap">
Select a font to view from the list below.
You can change the text by typing in the region at the bottom.
</TextBlock>
</Border>
<ListBox x:Name="FontList" DockPanel.Dock="Left" ItemsSource="{x:Static Fonts.SystemFontFamilies}" Width="160" />
<TextBox x:Name="SampleText" DockPanel.Dock="Bottom" MinLines="4" Margin="8 0" TextWrapping="Wrap"
ToolTip="Type here to change the preview text.">
The quick brown fox jumps over the lazy dog.
</TextBox>
<StackPanel Margin="8 0 8 8">
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="10" TextWrapping="Wrap" Margin="0 0 0 4" />
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="16" TextWrapping="Wrap" Margin="0 0 0 4" />
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="24" TextWrapping="Wrap" Margin="0 0 0 4" />
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="32" TextWrapping="Wrap" />
</StackPanel>
</DockPanel>
</Window>
![]() |
图3.4 我们的第一个WPF应用程序运行效果
注意到了吗?现在我们的程序拥有了本课程开始时我们所列出的所有功能并且能够正确的运行了,但是我们并没有写一行代码。
如果我们可以这么做,那后台代码存在的作用又是什么呢?我们一点而代码也没有写啊!
事实上,我们故意的以一个十分简单的应用程序来开始WPF的学习的。当我们要解决的问题变得更复杂的时候编写后台代码就显得十分必要了。尽管如此这还是证明了WPF的一个有力的特性:你可以做许多事情而不用写任何代码!
总结
在这个小时的课程中,我们谈到了如何建立一个新的WPF工程、然后我们建立了我们的第一个WPF应用程序:Font Viewer。我们也讨论了XAML文件和后台代码文件的区别。最后我们在一个较高的层次演示了WPF的一些令人印象深刻的特性——数据绑定、布局和声明式的编程。
问答
问. 哪些文件是自动的加入到WPF工程中的?
答. App.xaml、Window1.xaml以及它们的后台代码文件。前者(App.xaml)表示整个应用程序,后者(Window1.xaml)则表示应用程序的主窗体。
问. Xaml文件与后台代码文件之间有什么不同?
答. XAML文件里面的内容是标记语言而后台代码文件是与XAML文件想关联的里面包涵的是代码(例如C#代码或者VB代码)
问. 当你在VS中重命名XAML文件的时候与之关联的后台代码文件受影响了么?
答. 是的,后台代码文件也同时重命名了,但是类名并没有改变因此如果你想保持类名与文件名同步的话你必须手动的更改类名。
从Word里转过来就成了这种效果了,大家多多包涵,有错误的地方也请多多指正。
本站采用创作共用许可 署名,非商业 欢迎转载,转载请注明出处,并包括此段声明 。 Cat_Lee @ cnblogs
本系列文章的翻译并没有经过原著者的同意,仅做学习交流使用,如果您要使用本系列文章于其它用途请慎重,本人概不负任何法律责任。
Finish Whatever U've Started !!!