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新功能