WPF 基础到企业应用系列3——WPF开发漫谈(转)
1.开篇前言
首先很高兴这个系列能得到大家的关注和支持,基于对大家负责和对自己负责的态度,我会不断努力写好这个系列,分享自己的微薄技术和经验,希望在帮助别人的 同时也不断提升自己。由于这篇文章稍多,所以读者花的时间长了一些,也希望大家能够见谅,这个系列以后会每周发三到四篇左右(主要是写一篇差不多要花几晚 上,感觉思维比较发散),除了讲WPF技术本身之外,也会讲一些项目具体开发,所以敬请关注。在前两次的文章中我们对WPF有了一个比较全面的认识,那么 在本篇文章当中,除了讲一些理论知识外,我们会从实际的开发中进行讲解,用理论和代码的形式来诠释WPF的简单开发过程。
2.本文提纲
· 1.开篇前言
· 2.本文提纲
· 3.WPF开发基础
· 4.Expression系列工具简单介绍
· 5.其他工具介绍
· 6.WPF和WinForm案例
. 7.漫谈WPF开发
· 8.本文总结
. 9.系列进度
3.WPF开发基础
本系列文章默认情况下,开发环境为Windows XP+SP3英文版和Visual Studio 2008+SP1英文版。要使用Windows 7 Professional和Visual Studio 2010开发环境的时候会附加说明。在搭建好开发环境之后,打开VS2008,选择创建项目(Create Project),出现如下图所示的选择项目模板的对话框:
在项目模板选择对话框中选择WPF Application,修改项目名称(Name)(已经截图完毕,所以没能改名,望见谅),和存储位置(Location),点击 确定 (OK)按钮,便成功创建了一个WPF应用程序,模板中文件层次结构如下图所示(在References里面自动引入了图一中的 PresentationCore、PresentationFramework、WindowsBase三大核心程序集):
图二
在App.xaml中,指定项目运行时启动的是窗体:Window1,还可以定义我们需要的系统资源以及引入程序集等,详细看下图介绍:
在Window1.xaml中设计窗体的外观,首先,我们将窗体的Title更改为:XAMLWithScript,然后设置窗体的其他属性和事件 。完成了这些设置以后,我们就可以对窗体添加内容了,本实例对窗体添加了一个Button,然后对Button进行了一些简单的设置,详细如下图所示:
上图没有对一些概念讲全,所以下面这幅图用另外一个窗体对某些概念进行了补充,由于我把很多概念都画到了图里面,所以在此就不做过多解释,详细如下:
由于每个概念都比较细且多的缘故,所以这里只是对一些基本的概念和元素进行了展示,后续文章会做一一介绍,也欢迎和大家一起讨论!
4.Expression工具的使用
由于自己主攻方向不在这个方面,所以对这些工具也只是会使用而已,会用Expression做一些基本的效果和应用,但更多时候都是在visual studio里面手写代码,不过有的时候为了配合美工进行代码集成,也会接触这些工具。
在 Expression Design 中打开作品文件。(这个作品有可能是你用其他工具创建的,也可以是你用Expression Design 设计的,但个人认为它还是没有Photoshop/CorelDraw/Fireworks等工具好用。)
如果要导出切片,请从“工具箱”中选择“切分”工具,围绕所要导出的作品区域绘制一个矩形,然后在“属性”面板中的“编辑切片”下,设置切片的属性(如“Name”)。
单击“文件”菜单上的“导出”。此时,将显示“导出”对话框。
在“要导出的项”下,选择以下选项之一:
- “整个文档” 导出文档中的所有作品。
- “选定对象” 只导出那些在美工板上选定的项目。
- “切片” 只导出生成的切片。您可以根据情况选择更改所显示的每个切片的属性。
接下来设置“格式”,请选择以下任一选项:
- “XAML Silverlight 画布” 导出单个 XAML 文件,其中包含表示为画布版式面板中的对象的所有作品。您可以在 Expression Blend 3中将此 XAML 文件导入到 Microsoft Silverlight 项目内,以用作独立的文档(启动的 XAML 文件或以编程方式加载的 XAML 文件),或将对象复制并粘贴到另一个 XAML 文档中。
- “XAML WPF 图形画笔” 导出一个资源字典,其中包含表示为图形画笔资源的所有作品。您可以在 Expression Blend 3 中将此 XAML 文件导入到 Windows Presentation Foundation (WPF) 项目内,然后将这些资源应用于项目中的对象的画笔属性。
- “XAML WPF 画布” 导出单个 XAML 文件,其中包含表示为画布版式面板中的对象的所有作品。您可以在 Expression Blend 3 中将此 XAML 文件导入到 Windows Presentation Foundation 项目内,以用作独立的文档(启动的 XAML 文件或以编程方式加载的 XAML 文件),或将对象复制并粘贴到另一个 XAML 文档中。您还可以在 Expression Blend 3 的“设计”视图中打开该文件,右键单击任意一个或多个对象,然后通过选择“工具”菜单上的选项,利用这些对象来创建按钮或用户控件。
在对话框底部的“位置”框旁边,键入导出文件所在的文件夹的路径(我们这里就保存在D盘)。还可以设置下列选项:
如果决定导出“整个文档”或“选定对象”,还需要输入文件的名称。如果决定导出“切片”,则可以根据情况选择一个版式面板以包含所有对象。
单击“全部导出”以导出文件。
在 Expression Blend 3 中打开的项目内,单击“项目”菜单上的“添加现有项”。
在“添加现有项”对话框中,浏览找到所导出的一个或多个 XAML 文件,选择这些文件,然后单击“打开”。
5.其他的一些工具
除了上面我们用到的Expression Design、Expression Blend和Visual Studio以外,我们还会用到一些其他的工具,比如一些调试工具、一些性能优化工具和XAML查看工具。
KaXaml是一个轻量级的XAML编辑器,用它之前我们一直都是用XAMLPad,但是用了KaXaml以后才发现XAMLPad是那么的不好用,并且KaXaml是开源的,在codeplex上进行了发布,感兴趣的朋友也可以下载它的源代码进行研究。
它主要的功能如下:
1,内置诸多代码片段(模版)
2,内置ColorPicker
3,xaml scrubber : 可以帮你清理你的XAML代码
4,支持语法高亮和智能提示
其他的一些工具和资源,园子里周金根做了一些收集,我在这里也不做一一介绍了,大家可以看一下他的博客,详细地址:WPF - 资源收集,我觉得整理的非常的不错。
6.WPF和WinForm案例
介绍
这个例子主要展示同一个需求用WinForm和WPF分别进行实现,通过这个例子,我们可以看到两者之间的区别和联系,同时也可以对我们的项目选型 带来一定的参考作用(原型来自于Josh Smith的一篇文章,个人觉得讲得非常不错,所以对原有例子进行了改造,进而有了这个案例)。
当然作为一项新技术,WPF带来了很多功能,但在使用这些功能的同时也会带来很多缺点,这是不可避免的,正所谓”有利必有弊“吧!所以我们这个例子并不是讲WPF有如何如何的好,怎样用WPF代替WinForm,而是从两者实现同一个需求进行简单的对比。
这个例子是用Visual Studio 2008编写的,所以大家可以下载下来进行查看.
特别声明
这个程序并不是要展现声明优秀的架构也不是为了宣扬WPF的种种好处,所以没有采用当前比较热门的MVP、MVVM模式进行开发,同时项目当中你可 以看到很随意的代码,没有对IOC、AOP以及设计模式进行应用,这也是考虑到具体需求和例子简单的原因,况且这里也没有必要,我们在做项目的时候也要时 刻注意什么时候用什么开发框架、开发模式以及项目整体架构。
程序概览
这个例子非常简单,需求就是展示三大社区的基本信息,同时你可以在输入框对其进行修改,当焦点切换的时候,你就会看到它会自动进行修改,你把鼠标放 在图片上面会提示社区的ID等等。我在这里没有用复杂的逻辑和高深的架构,只是想通过这个例子展示WinForm的WPF的差异和联系,所以在程序处理上 可能会有很多漏洞,比如没有对输入进行验证,你可以输入空格和任意字符等。
下面是WinForms版本的截图:
下面是WPF版本的截图:
如果你编辑了某个社区的中文名称或者英文名称,然后把焦点移到另外一个地方,这些更改就会通过右上角的全名体现出来,因为他们都是通过绑定到公用字段来实现这些操作的。
整个项目结构如下图所示:
整个项目一共就三个工程,第一个工程BusinessObjects 是WpfApp和WinFormsApp公用的业务类库,WinFormsApp是用WinForm实现的版本,WpfApp是用WPF实现的版本。那么我们下面就简单分别进行一些介绍:
公用代码部分(BusinessObjects)
这两个应用程序都是使用的BusinessObjects作为逻辑类库,BusinessObjects中的Company对UI所使用的数据进行了Mock。所以他们在需求方面都是一样的,由于比较简单,所以请看下面代码:
Collapse
using System;
using System.ComponentModel;
using System.IO;
using System.Reflection;
namespace BusinessObjects
{
public class Company : INotifyPropertyChanged
{
#region Creation
public static Company[] GetCompanys()
{
// In a real app this would probably call into a data access layer to get records from a database.
return new Company[]
{
new Company(1, "博客园", "CNBlogs", GetPictureFile(1), new DateTime(2004, 1, 12)),
new Company(2, "51CTO", "51CTO", GetPictureFile(2), new DateTime(2005, 3, 1)),
new Company(3, "CSDN", "CSDN", GetPictureFile(3), new DateTime(2000, 1, 20)),
};
}
private static string GetPictureFile(int CompanyID)
{
string fileName = String.Format("emp{0}.jpg", CompanyID);
string folder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
folder = Path.Combine(folder, "Images");
return Path.Combine(folder, fileName);
}
private Company(int id, string chineseName, string EnglishName, string pictureFile, DateTime startDate)
{
this.ID = id;
this.chineseName = chineseName;
this.EnglishName = EnglishName;
this.PictureFile = pictureFile;
this.StartDate = startDate;
}
#endregion // Creation
#region Properties
public int ID { get; private set; }
string _chineseName;
public string chineseName
{
get { return _chineseName; }
set
{
if (value == _chineseName)
return;
_chineseName = value;
this.OnPropertyChanged("chineseName");
this.OnPropertyChanged("FullName");
}
}
string _EnglishName;
public string EnglishName
{
get { return _EnglishName; }
set
{
if (value == _EnglishName)
return;
_EnglishName = value;
this.OnPropertyChanged("EnglishName");
this.OnPropertyChanged("FullName");
}
}
public string FullName
{
get { return String.Format("{0}, {1}", this.EnglishName, this.chineseName); }
}
public string PictureFile { get; private set; }
public DateTime StartDate { get; private set; }
#endregion // Properties
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}上面这段代码没有什么不寻常的地方,大家写WinForm和Asp.Net也会写这样的逻辑类,只是要注意Company 实现了INotifyPropertyChanged 接口,大家看到这个接口只有一个OnPropertyChanged的方法,这个方法就是我们要说的属性变更通知方法,就是说当一个属性改变了,我们需要做些什么来响应这些改变。
- WinForms实现介绍
WinForms版本就包含一个
Form
和一个展示社区信息的customUserControl
, 这个Form
包含了一个FlowLayoutPanel控件
, 它主要的作用就是用来承载每个社区的实例. 那么代码就如下所示:Collapse
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// Create and initialize a usercontrol for each Company.
foreach(Company com in Company.GetCompanys())
{
CompanyControl comCtrl = new CompanyControl();
comCtrl.Company = com;
this.flowLayoutPanel.Controls.Add(comCtrl);
}
}
}CompanyControl是我们创建的一个UserControl,由于每个CompanyControl都要显示一个Company对象的属性值,我在这里使用了BindingSource控件来进行绑定,这样做也是为了和WPF更接近考虑(增强对比性,呵呵)。具体如下截图:
如上图所示,我们用了BindingSource来获取数据,但有一个属性除外,那就是Company ID,请看下面代码:
Collapse
namespace WinFormsApp
{
///
/// A WinForms control that displays an Company object.
///
public partial class CompanyControl : UserControl
{
public CompanyControl()
{
InitializeComponent();
// Convert the picture file path to a Bitmap.
Binding binding = this.CompanyPicture.DataBindings[0];
binding.Format += this.ConvertFilePathToBitmap;
}
void ConvertFilePathToBitmap(object sender, ConvertEventArgs e)
{
e.Value = Bitmap.FromFile(e.Value as string);
}
public Company Company
{
get { return this.CompanyBindingSource.DataSource as Company; }
set
{
this.CompanyBindingSource.DataSource = value;
// The Company's picture shows a tooltip of their ID.
if (value != null)
{
string msg = "Company ID: " + value.ID;
this.toolTip.SetToolTip(this.CompanyPicture, msg);
}
}
}
}
}这里有几点需要注意.在绑定的时候,我们对PictureFile 字段进行了转换,这个是必须做的. 如果不那样做, 这个图片会绑定失败,因为在绑定的时候它不能自动把
string类型
直接转化为Image类型
.现在我们已经把Company绑定到了我们的控件上, 这里我需要给
PictureBox一个
tooltip的效果. 这个tooltip将显示 CompanyID
, 前缀显示为 "Company ID:". 现在这个是在代码里面写的,没有在窗体中发现有WPF ToolTip等类似的工具,不知道大家用到过没有?总的来说, 这是一个很简单的例子,我们的大部分功能也是用代码没有写代码,是通过visual designer进行实现的.然后通过一部分代码把它衔接起来, 我们看到Windows Forms是一个非常快速和实用的开发平台.
WPF实现介绍
WPF版本我这里就做得很简单了,由于开发WPF程序提供了很多模板和工具,所以我这里基本没写什么代码,全部的代码都是通过XAML实现,并且大部分都是自动生成的,只是我们要根据项目具体情况做一些修改就行。
这个WPF项目同样有一个
Window
和一个customUserControl
, 和 WinForms 版本基本一样. 只是WinForms中用FlowLayoutPanel
来承载EmployeeControl
s 控件, 而WPF 用的是ItemsControl
来承载这个用户控件.更加可喜的是,WPF通过模板来进行定制,所以我们就不需要像WinForms那样写循环加载控件的代码,下面就是WPF用XAML实现的窗体代码:Collapse
<Window
x:Class="WpfApp.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp"
xmlns:model="clr-namespace:BusinessObjects;assembly=BusinessObjects"
Title="WPF App" Height="558" Width="581"
WindowStartupLocation="CenterScreen"
>
<Window.DataContext>
<ObjectDataProvider
ObjectType="{x:Type model:Company}"
MethodName="GetCompanys"
/>
Window.DataContext>
<Grid Width="555">
<Label
Name="label1"
HorizontalContentAlignment="Center" VerticalAlignment="Top"
FontSize="20" FontWeight="Bold"
Height="36.6" Margin="0,16,0,0"
>
.NET 中文社区大比拼Label>
<ItemsControl
ItemsSource="{Binding}"
HorizontalContentAlignment="Center"
Margin="46,59,25,0"
Focusable="False"
>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:CompanyControl />
DataTemplate>
ItemsControl.ItemTemplate>
ItemsControl>
Grid>
Window>在如下的XAML代码中,这里有几点需要注意,。Window的DataContext赋予了一个ObjectDataProvider的对象,而ObjectDataProvider又会调用GetEmployees这个方法。所以一旦把DataContext设置到Company 对象,并且把ItemsControl的ItemsSource设置为“{Binding}” 就意味着该控件里面会自动显示Company 对象的所有数据。
这里我们并不需要像WinForm一样用循环的方式创建CompanyControl的实例。这是因为ItemsControl中的ItemTemplate属性设置为了一个DataTemplate,同时ItemsControl中的ItemsSource绑定到了Company 的对象数组,那么ItemTemplate就会知道如何创建一个CompanyControl,所以大家看到这里写的代码就相对变少了,这也是XAML的一个优点之一。
该CompanyControl的后台CS文件也是空的(除了必须的InitializeComponent),所以它不像的WinForms应用 程序那么累赘,界面和逻辑紧密的耦合在了一起。下面就是CompanyControl的XAML代码, 这个代码相对来说就比较简单了。
Collapse
<UserControl x:Class="WpfApp.CompanyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="137" Width="481">
<Border
BorderBrush="Black"
BorderThickness="1"
Margin="2"
SnapsToDevicePixels="True" Width="469">
<Grid Height="129" Width="451">
<Image Source="{Binding PictureFile}"
Margin="10" Name="image1" Stretch="Fill"
Width="150" Height="80" HorizontalAlignment="Left" >
<Image.ToolTip>
<TextBlock>
<Run TextBlock.FontWeight="Bold">Company ID:Run>
<TextBlock Margin="4,0,0,0" Text="{Binding ID}" />
TextBlock>
Image.ToolTip>
Image>
<Label
Content="{Binding FullName}"
Height="34" Margin="99,2,0,0"
Name="中英文名称"
VerticalAlignment="Top"
HorizontalContentAlignment="Right"
FontSize="16" FontWeight="Bold" />
<Label Margin="190,34,0,0" Name="chineseNameLabel"
FontWeight="Bold" Height="28"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Width="73">中文名称:Label>
<TextBox
Text="{Binding chineseName}"
HorizontalAlignment="Right" Margin="0,39,10,0"
Name="textBox1" Width="172" Height="23"
VerticalAlignment="Top" TextDecorations="None" />
<Label FontWeight="Bold" Height="28" Margin="190,0,0,34"
Name="EnglishNameLabel" VerticalAlignment="Bottom"
HorizontalAlignment="Left"
Width="73">英文名称:Label>
<TextBox
Text="{Binding EnglishName}"
Height="23" Margin="0,0,10,34" Name="textBox2"
VerticalAlignment="Bottom" HorizontalAlignment="Right"
Width="172" />
<Label Height="28" Margin="190,0,185,2"
Name="startDateLabel" VerticalAlignment="Bottom"
FontWeight="Bold">创建日期:Label>
<Label
Content="{Binding StartDate}"
Height="28" HorizontalAlignment="Right" Margin="0,0,10,2"
Name="startDateValueLabel" VerticalAlignment="Bottom"
Width="172" />
Grid>
Border>
UserControl>如上面的代码所示,UI上的很多元素我们都可以通过拖控件进行实现,有个功能需要自己简单的写一写代码,UI上面有一个功能就是你把鼠标放在图片上的时候会提示Company ID,这个功能通过
ToolTip属性进行实现的。
ToolTip
属性是WPF所有元素的基类FrameworkElement的一个属性,所以我们可以在这些子元素当中直接使用。那么大家注意到,这个小功能在WinForm中我们要写一些代码,而在WPF就可以直接通过属性定制,所以在很多方面WPF对这些方面都做了封装和简化,也提高了我们的开发效率。
案例总结
通过上面的案例,我们主要认识到:如果不需要强大的图形和显示效果,WinForms和WPF 都能完成同一个需求,只是WinForms在设计的时候比较痛苦一些,并且没有单独把UI分立出来,所以很多时候都会和逻辑进行耦合;而WPF就不一样 了,它用XAML来进行UI的设计,然后用后台C#或VB等语言来进行操作,这样就使职责进行了分立,使每个部分都发挥到了最好,同时也提高了开发效率。
对于长期从事WinForms或者其他没有从事过ASP.NET等开发人员, 可能不太习惯XAML的这种开发习惯. 但对于ASP.NET 的开发者来说上手就比较容易一些了,因为在很多方面它和HTML有很多相似之处. 不过也没有关系,只要做了一段时间以后就会发现XAML代码是那么的有趣,以至于看到它就有一种亲切感!
这个案例并不是介绍我们如何放弃WinForm和如何转向于WPF,只是想通过他们的异同进行一下简单的对比,大家都知道WPF的特长在于UI和逻辑的分 离、强大的动画和图形效果,但是性能却是一个摆脱不去的瓶颈。而WinForm正好相反,它在性能上得到了比较好的体现,但在显示强大动画和图形效果以及 一些高交互的效果方面就显得不能为力了,所以我们在做项目的时候应该有一个权衡,尤其是在现在的硬件和软件基础上。
8.漫谈WPF开发
谈到WPF的开发,就不能不说到MVVM,一说到MVVM,就会提及MVC、MVP等概念,那么这样一关联下来就会产生很多概念,到最后就很容易变成以概 念来阐述概念,最终的结果可想而知,大家可能会一头雾水、不知所云,所以我用“漫谈WPF开发”这个小标题来阐述一下我对WPF开发的理解,当然只是自己 对这些技术的总结和经验,错误之处在所难免,也希望大家能够谅解!
从2007年接触WPF和Silverlight以来,也做过一些项目了,对他们也有一些自己的理解,当然在开发这些项目的过程中也在使用其他的一 些技术做项目,比如WinForm、ASP.NET(ASP.NET MVC一个项目没做完就被终止)等等,感觉不论是采用什么技术,最基本的东西都不会变,比如对数据库和文件的访问、对日志和异常的处理、对报表的展现、对 打印的实现、对性能的提升、对用户的友好等等。
那么这些项目也为我们积累了不少经验,有技术上的也有其他方面的:
- 为了应付项目需求的不断变化和项目的可扩展性,我们也会引入OO和设计模式;
- 为了解除各模块和组件的耦合,我们也会利用IOC的思想解耦;
- 为了让逻辑代码清晰且没有其他代码的干扰,我们也会采用AOP的方式进行代码重组;
- 为了使项目的开发速度更快且更方便,我们也会引入ORM思想来加快项目的开发速度和可维护性;
- 为了更好组织各层开发,隔开耦合,我们也会采用MVC、MVP、MVVM模式;
- 为了提升用户的响应速度,我们会采用AJAX的方式来实现;
- 为了降低系统的负载同时提高用户的响应能力,我们也会采用MSMQ或者SSB来组织消息队列;
- 为了规范各系统的接口,提供一个统一的交互平台,我们也会采用SOA;
- 为了降低服务器的负担和提高速度,我们也会自己写一套缓存;
- 为了把产品做好,我们也会不断优化技术;
- 为了能做好外包项目,我们会不需要任何高深技术;
- 为了能得到客户满意老板好评,我们也会学会如何交流;
其实归根到底就是要分清关系,理清思绪,既要处理好与机器的关系,也要处理好与人的关系,只有这样才能把产品或者项目做成功,我也在不断学习当中,所以如果大家有一些这方面的问题和建议,我们也可以互相讨论。
前面不知所云的漫谈了一通,那么我们到底该怎么认识WPF项目的开发呢?我个人的观点是和其他技术一样,假如这是一个比较小的而且需求改动很小的项目,那 么我不建议用一些高深的技术,因为它要的是马上看到效果和时间上的优势,所以应该抛弃我们的技术思想。当遇到一个比较大型的项目而且需求可能变动很大,那 我们得慎重考虑系统的构架了,因为很多时候我们都会发现我们的系统无法再扩展了,这就是一个很大的“杯具”了。那么作为一个项目,我们怎样才能在事前做好 呢?我觉得有以下几个方面:
- 项目情况把握:首先我们要分析项目的背景、项目的目的、项目的前景、项目的需求、项目的客户、项目的实现难度、项目的规模、项目所使用的技术、项目的最终效果等因素,只有把握好了这些方面以后,我们才能做到对项目知根知底且游刃有余。
- 项目团队把握:首先分析一下自己的团队成员组成结构,有没有领域分析人员?有几个架构师?有没有Team Leader? 有几个senor developer?有几个developer?有没有测试人员? 有没有项目配置管理员?有没有QA以及有没有类似的项目经验等。知道这些可以合理安排任务,这正是对自己团队的把握。
- 开发模式把握:不论你是开发产品还是做项目,我们都需要采取一种适合的模式,那么什么叫适合呢?这个没有准确的答案,只有根据具体情况具体分析 了,如果需求比较明确且系统较大,那我们就可以用传统的瀑布模型进行开发,只要客户能接受同时自己做好各方面的监控,应该问题不大;如果需求不是很明确且 周期很长,我们可以用迭代的方式进行开发,这样客户也能更加明确自己的需求同时也能看到自己想要的效果。当然如果需求不明确而且有很多不确定因素,我们也 可以采用TDD的方式进行开发,如果把握得好,这样慢慢也会形成一个比较好的项目。
- 开发规范把握:作为一个多人开发的团队,没有一些规范是不行的,团队管理规范、项目管理规范、代码书写规范、开发流程规范、测试规范等等,这些都是要在开发之前定好,否则我们将会看到项目到处一盘散沙,无从管理。
- 其他方面规范:其他方面的规范就很多了,比如开发环境的规范、测试的规范、文档的规范、部署的规范等等,这个可以根据具体项目进行裁剪。
前面谈到了一些项目管理整体把握,总结就是大道至简、适可而止!那么我们如何才能在具体项目中引用一些其他技术呢?感觉思绪有点乱了,还是就此打住,等到了讲WPF具体项目或者具体技术的时候再讲,不然就真的一发不可收拾了。
9.总结
这篇主要从WPF的开发基础讲起,讲了一些WPF的开发工具等内容,用一个例子来对比了WPF和WinForm的异同之处同时也对某些技术进行了漫谈,通 过这篇文章,我们对WPF有了一个基本的了解,所以从下一篇文章开始我们将进入WPF的知识分类讲解,最后会以项目运用、优化和WPF4结束整个系列文 章。
最后圣殿骑士 会尽心尽力写好这个系列,同时由于是自己对这些技术的使用总结和心得体会,错误之处在所难免,怀着技术交流的心态,在博客园和51CTO发表出来,所以希望大家能够多多指点,这样在使一部分人受益的同时也能纠正我的错误观点,以便和各位共同提高,后续文章敬请关注!
10.系列进度(红色标示已发布)
· 5. 使用面板做布局(几种布局控件的XAML及CS代码,综合布局等)
· 6. 依赖属性、附加属性(基本、继承、元数据)
· 7. 路由事件、附加事件
· 8. 命令
· 9. WPF控件分类介绍与使用技巧(ContentControl、HeaderedContentControl…… Decorator)
· 10. 尺寸缩放、定位与变换元素
· 11. 资源
· 12. 数据绑定(基本、值转换、验证、集合的筛选、排序、分组、主从、数据提供者)
· 13. 样式
· 14. 模板
· 15. 多语言、皮肤和主题
· 16. 2D图形
· 17. 3D图形
· 18. 动画(几种动画的应用)
· 19. 音频、视频、语音
· 20. 文档、打印、报表
· 21. 用户控件和自定义控件
· 22. Win32、Windows Form以及ActiveX之间的互用性
· 23. 构建并部署应用程序(ClickOnce部署、微软setup /InstallShield+自动更新组件)
· 24. WPF的模式讲解及实例(MVC Demo)
· 25. WPF的模式讲解及实例(MVP Demo)
· 26. WPF的模式讲解及实例(MVVM Demo)
· 27. 性能优化(WPF项目的瓶颈)
· 28.一个完整WPF项目(普通架构版)
· 39. 一个完整WPF项目(MVVM架构版)
· 30. WPF 4.0新功能