入门教程系列一创建你的第一个项目潇洒

快速学习绝不是从零学起的,良好的基础是快速入手的关键,下面先为大家摞列以下自己总结的学习WPF的几点基础知识:

1) C#基础语法知识(或者其他.NET支持的语言):这个是当然的了,虽然WPF是XAML配置的,但是总还是要写代码的,相信各位读者应该也都有这个基础了。

3) 对C#中的代理、事件要做到熟练掌握,在.NET 3.0 版本后有增加了Routed Events,要想日后不糊涂,这个是基础。

5) 拥有良好的面向对象的思想:思想是语言的升华(本人的OO思想完全是Java中领悟来的)。在WPF中,经常要灵活运用各种继承关系、多态、重载等,因此一定要把基础知识打牢固。

7) 对设计模式要有一定的了解:当然是越深入越好了,在实际项目中,各种设计模式经常交融使用。

快速的识别并合理的运用,无论是在开发还是调试时都是非常高效的。另外,WPF存在的初衷即是表现与逻辑的松耦合,最普遍的情况就是XAML作为表现层,背后.cs文件作为逻辑层。因此,日后在从事项目工作时,要时刻谨记这一点,千万不可背道而驰。

不要为了凸显自己的某一些代码特长而将各种逻辑混写在一起,这样非常不实际的,这一点都在校生应该尤为重要。

8) 对XML的理解:XAML也是XML,对XML的理解绝对有助于快速的接受和使用XAML,并不需要多XML有多么高深的见解。

开发环境:VS 2008

数据库:本机SQL Server 2005(这里给大家一个提醒,如果大家的机子是Windows XP的话,无论是home 或是 professional.

一定不要安装SQL Server 2005 Enterprise Edition,在《安装 SQL Server 2005 的硬件和软件要求》中“操作系统要求”列表有写到2005 Enterprise Edition 不支持 XP),建议安装Developer Edition,一定要安装数据库实例。

具备以上基础条件后,开始入手练习,大家不要抱怨入手练习有写难度,毕竟是快速入门要有一定的跳跃性:

我们要做一个WPF程序,功能很简单:

2) 当鼠标或其他设备选中结果某一项记录时,在List框下面展示出细节。

3) 修改其中的内容后,结果联动更新到List框及数据库中。

想象以下这样一个东西如果在以前使用winform实现会是什么样子呢?

应该会写不少的方法、属性用于界面之间及界面与数据库之间的联动。

今天这个练习就先展示以下WPF的技术亮点之一:

DataBinding。在制作过程中,还会为大家不断接受一些控件、布局等相关知识和技巧,部分相关的知识内容与此练习关系不大的,我将会用浅灰色字体带过,对于熟悉这部分内容的读者可以直接跳过。

打开VS 2008 新建一个WPF应用程序

首先会看到一个靓丽的小方框,将鼠标放在方框的边缘点击就会产生相应的分割线。

现在我们要做的内容需要将窗体分成三行,可以先随便分割一下,以后在调整相互的大小。这时候会注意到下方的XML代码区域。每个RowDefinition作为一个行被定义出来

这里先给大家接受以下高度、宽度的几种定义方式(写过HTML的人可以跳过去了):

绝对尺寸(Absolut sizing):就是给一个实际的数字,像现在例子中那样

自动(Autosizing):值为Auto,实际作用就是取实际控件所需的最小值(Setting Height or Width to Auto, which gives child elements the space that they need and no more)。

Proportional sizing(也可以称之为star sizing因为有个*号表示):

值为*或N*,实际作用就是取尽可能大的值,当某一列或行被定义为*则是尽可能大,当出现多列或行被定义为*则是代表几者之间按比例方设置尺寸。

下面我们来将上面的知识应用以下看看。

将这三行的值设置为如下数值,结果会是如何:

<RowDefinition Height="*" />

<RowDefinition Height="Auto" />

<RowDefinition Height="22" />

第0行设为*用来放置ListView,这样会在实际运行过程中尽可能的充满整个区域

第1行设为Auto尽量紧凑配列,少占用空间(如果里面没有东西的话,他会小到0,这是你会看不到它)

第2行设为22固定值,只是用来放一个Button使用

对于初学者往往会习惯直接使用控件拖拽的形式来将需要的内容添加到窗体上。

会使控件在一定的坐标上固定位置,这是一种不推荐的做法,在此给大家讲解以下WPF中的布局观(Layout Philosophy):

在WPF窗体中,一个窗体只能持有一个控件,当多个控件想要在窗体中展现时,就需要首先设置一个容器控件(Container)

然后将其他控件放到这个控件里面,形成树状结构.

因此,布局观第一条就是,控件的布局应该有容器来决定,而不是通过自身使用margin之类的东西来控制位置。

因为这些属性原本应该是控制自己内部展现或与邻里之间关系的;

第二条,控件应避免明确的定义具体的尺寸,因为显示器分辨率及windows窗体的大小都有可能随时改变,如果明确的定义尺寸。

当窗体变动后就会出现大面积的空白或是缺失。但为了控件功能及效果的展示,应该限定一个可接受的最大及最小尺寸。

通过MinWidth, MinHeight, MaxWidth, MaxHeight属性可以实现这一点。第三条,不要将界面元素位置设置成与屏幕坐标相关.

现在显示器分辨率比较多样话(800×600、1024×768,我的显示器是一台是1400×1050,还有一个是1024×1280竖式的),这样的做法还是比较有风险的。

第四条,容器应将有效空间共享给其子控件,这也是为了不在窗体调整后,遗留出大块的空余。

第五条,容器嵌套使用,因为不同的容器,表现效果不同,必要时应结合使用。

接下来在工具箱(Tool Box)中双击ListView,一个小框会出现在界面上。

接下来在工具箱(Tool Box)中双击WrapPanel,又一个大框会出现在界面上。

再增加一个Button。

这是你会感觉到界面有点乱了,刚才我们在顶层Grid上面画线到底起什么作用了(到目前位置还没有),让我们来调整一下下面的XAML语句,最终结果如下:

<Grid>

<RowDefinition Height="*" />

<RowDefinition Height="Auto" />

<RowDefinition Height="22" />

<ListView Name="listView1" MinWidth="280" >

<GridView x:Name="gridView1">

<GridViewColumn Header="ContactID"></GridViewColumn>

<GridViewColumn Header="FirstName"></GridViewColumn>

<GridViewColumn Header="LastName"></GridViewColumn>

<GridViewColumn Header="EmailAddress"></GridViewColumn>

</GridView>

</ListView>

</Grid>

这里有几点又需要解释以下了:

1)      介绍以下容器控件Panel,现在界面中有两个容器型的控件一个是Grid跟元素,另一个是WrapPanel。它们都是容器型控件,不过表现上有所不同。

Grid顾名思义“网格”,在之前我们已经定义了三行高度分辨是*, Auto, 22,其实还可以功过ColumnDefinition定义多个列,他的子控件被放在一个一个实现定义好的小格子里面,整齐配列。

而WrapPanel则是将各个控件按照行或列的顺序摞列,当长度或高度不够是就会自动调整换例或行。

还有一个常用控件这里稍后会用到StackPanel,将控件按照行或列来顺序排列不会回行。

用来设置WrapPanel及Button应该在父容器的什么位置。这是WPF的特性之一,通俗的理解起来就是,别人有的属性,由于你跟他产生了关系所以你也有了这个属于他的属性。

记得FantasiaX‘水之真谛’曾经给我通俗的解释过这个特性,这里照搬出来分享给大家:一个小学生,身高、体重是他的自身属性,而这个小学生由于是N年级的X班的学生.

因此,这个小学生又带有了一个附加的属性,N年级X班。在这个例子里如果学校作为一个Grid容器,N年级X班可以看作一个小格子,小学生是其中的一个实例,那么,小学生因为安置在这个班级.

因此获得了这个班级所拥有的这个属性,当学期末,老师说,这个学生已经升到N+1年级X班时,这个学生以后就跑到另一个小格子里去上课了。

其实就是元素的某一个属性由于不能够简单的用名值对实现,因此需要单独标签话声明一下。

4)      再有就是x:Name="gridView1"这种用法,叫做Markup Extensions(‘标记扩展’吧),这个可是一个满不错的特性.

由于后面代码中要使用到GridView对象,然而GridView对象有没有Name属性,如果后台代码想要调用他的话就不得不从父容器向下遍历来找到想要的对象,这样无疑增加了后台代码与前台界面之间的耦合度,试想如果那天突然有需求说要把这个对象从这里移到另一个容器上去.

那么界面的变动伴随着的就是后台代码的一起变动,这与视图/逻辑分离显然背道而驰,有了Markup Extensions.

我们想定位一个没有名字属性的控件,直接为扩展一个名称出来,这个可太方便了(当然,Markup Extensions不只是用来扩展名称的)。

如果希望每个TextBlock和TextBox成为一对出现的话,应该如何呢?

自然是需要一个容器将他们组织起来.

同时,希望他们在一条线上不回行。这就用到了,我们前面说到的一个容器StackPanel。组织后的代码如下:

<StackPanel Orientation="Horizontal" Margin="5,2,5,2">

<TextBlock Name="textBlock_ContactID" Text="ContactID:" />

<TextBox Name="textBox_ContactID" MinWidth="100" />

</StackPanel>

<StackPanel Orientation="Horizontal" Margin="5,2,5,2">

<TextBlock Name="textBlock_FirstName" Text="FirstName:" />

<TextBox Name="textBox_FirstName" MinWidth="100" />

</StackPanel>

<StackPanel Orientation="Horizontal" Margin="5,2,5,2">

<TextBlock Name="textBlock_LastName" Text="LastName:" />

<TextBox Name="textBox_LastName" MinWidth="100" />

</StackPanel>

<StackPanel Orientation="Horizontal" Margin="5,2,5,2">

<TextBlock Name="textBlock_EmailAddress" Text="EmailAddress:" />

<TextBox Name="textBox_EmailAddress" MinWidth="100" />

</StackPanel>

</WrapPanel>

这样情况下在试试就可以看到效果了,无论窗体边缘怎么托拉TextBlock和TextBox总是成对的.

同时,随着窗体的拖动,控件会不断的改变位置一适应最小原则(如果想要让他固定下来的话.

那就需要将WrapPanel换成其他的Panel就可以了)。如下图所示:

补充知识:

与ContentControl平行的还有一类控件叫做 ItemsControl,WPF中所有控件集合对象的统称,例如:ListView, ListBox, TreeView等,这一点一定要区分清楚.

同时,实现Refresh按钮的方法。此部分不是练习重点这里不做介绍了,代码如下:

public Window2()

InitializeComponent();

getData();

SqlDataAdapter sda;

DataTable dt;

void getData()

//init sqlconnection

SqlConnectionStringBuilder connbuilder = new SqlConnectionStringBuilder();

//start to make sql query

SqlCommandBuilder commbuilder = new SqlCommandBuilder(sda);

dt = new DataTable();

private void button1_Click(object sender, RoutedEventArgs e)

getData();

Binding这个此翻译起来有争议,为了避免误导大家,因此我还是不写成中文了。

好了!接下来终于到最精彩的地方了。各位读者们一会会为后面所发生的事情而感到震惊的,一切就是这样的完成了……

1)      为ListView控件指明数据源,通过ItemSource属性设置,这一部分需要通过代码来实现(目前位置还不知道如何通过XAML语言来实现,哪位大哥可以指点一下)。

2)      给GridViewColumn指明当前列对应于数据源的哪一项,可以通过DisplayMemberBinding属性来实现.

<GridViewColumn Header="ContactID" DisplayMemberBinding="{Binding Path=ContactID}"></GridViewColumn>

<GridViewColumn Header="FirstName" DisplayMemberBinding="{Binding Path=FirstName}"></GridViewColumn>

<GridViewColumn Header="LastName" DisplayMemberBinding="{Binding Path=LastName}"></GridViewColumn>

<GridViewColumn Header="EmailAddress" DisplayMemberBinding="{Binding Path=EmailAddress}"></GridViewColumn>

此时试着F5 Debug运行以下,应该已经可以看到这样的画面了

接下来我们就来实现这部分功能。

1)      为了简化代码,在WrapPanel元素中指明一个公共的上下文,可以通过增加属性

DataContext="{Binding ElementName=listView1,Path=SelectedItem}

2)      分别为四个输入框指明相应的数据源,可以通过TextBox元素中的Text属性实现,实现后代码如下:

<TextBox Name="textBox_ContactID" MinWidth="100" Text="{Binding ContactID}" />

……

<TextBox Name="textBox_FirstName" MinWidth="100" Text="{Binding FirstName,UpdateSourceTrigger=PropertyChanged }" />

……

<TextBox Name="textBox_LastName" MinWidth="100" Text="{Binding LastName}" />

……

<TextBox Name="textBox_EmailAddress" MinWidth="100" Text="{Binding EmailAddress}" />

上面这一段代码相信有很多刚刚接触WPF的人一定会感到陌生,这里解释一下:

上面这段XAML语句里面,大家看着最不顺眼的应该就是{Binding …}这种语句了吧,这个就是WPF重要特性之一“Binding”。

他是用来实现界面元素的属性与后台数据之间的Binding,通过这种形式将前台界面与后台数据联系在一起达到界面与数据耦合的目的。

与直接覆值相比较,存在这如下几点特性上的差异:

1)      Binding可以通过XAML语句实现界面与数据(可以是界面元素或后台对象)的耦合(也可以通过代码来实现)。

这一实现主要是依靠WPF的另一个特性Dependency Property来实现的。示意图如下:

2)      Binding可以实现制定方向的绑定,方向有三种,OneWay, TwoWay, OneWaytoSource,其形象的表示如下图所示:

LostFocus :当控件失去焦点时触发,前面例子里

PropertyChanged:当属性改变时触发

Explicit:这个就可以看作是需要显示调用了,需要主动取调用相应的UpdateSource方法才可以触发

用法可以像这样“{Binding FirstName,UpdateSourceTrigger=PropertyChanged }”

4)      不抛出异常,这一点对于开发及测试人员来说可能并不怎么好。

当一个数据Binding失败是,程序运行是不受影响的,只是相应的属性值为空了,对于开发人员来讲只能通过VS Debug时的输出窗口看到Binding失败的调试信息。

而对于测试人员来说那就只能是靠肉眼了。

具体内容可以参考MSDN中的” Data Binding Overview”这篇文章,这里只是为大家实现一个引路的工作

现在再试试应该已经可以实现ListView与TextBox的联动了,不过此时,对数据的改动还无法更新到数据库中。

需要继续修改。

2)      在XAML设计区,最顶层Window元素中增加属性,Closed="Window_Closed",然后在后台实现相应的方法代码如下

两个方法具体代码如下,由于与WPF关系不大,因此不做讲解了:

private void button1_Click(object sender, RoutedEventArgs e)

getData();

private void Window_Closed(object sender, EventArgs e)

THE END
0.MySQL从入门到精通超详细版本,看这一篇就够了!mysql教程一、初识数据库 1. 数据库服务器、数据库与表之间的关系 数据库服务器上运行着数据库软件 数据库软件管理不同系统对应的数据库 数据库中包含很多张数据表 数据表中包含很多数据行 2. SQL简介 2.1 什么是SQL SQL(Structured Query Language)是结构化查询语言的简称,是一种数据库查询和程序设计语言,用于读取数 jvzquC41dnuh0lxfp0tfv87523e9396453:0c{ykenk0fnyckny03=<4:7:36
1.MySQL+JDBC全方位学习指南数据库基础学习一,数据库基础知识 1.数据库的概念 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库。它可以被视为一个电子化的文件柜,用户可以对文件中的数据进行新增、查询、更新、删除等操作。与传统的文件存储相比,数据库具有数据结构化、冗余度低、共享性高、独立性强等优点。 jvzquC41dnuh0lxfp0tfv8r2a99::9:891gsvrhng1jfvjnnu1762==5;;?
2.MySQL数据库基础知识点储备(整理总结)mysql教程MySQL数据库基础知识点储备(整理总结) 本篇文章给大家带来了关于mysql数据库的相关知识,主要整理了数据库基础的一下知识点,包括索引、语法顺序、执行顺序、存储过程等等相关问题,希望对大家有帮助。 推荐学习:mysql教程 一、数据库 1.1 事务 1.1.1 事务四个特性(ACID)jvzquC41yy}/rqu0ep5n{|vn/v{uq{ncnu35:B9950nuou
3.MySQL数据库基础实例教程(微课版)最新章节周德伟著数据库基础知识 【学习目标】 ● 了解数据库的基础知识。 ● 了解结构化查询语言的特点。 ● 掌握MySQL数据库的安装与配置方法。 ● 能使用多种方式连接、启动和运行MySQL服务器。 1.1 数据库概述 数据库技术是信息系统的一个核心技术。数据库技术产生于20世纪60年代末、70年代初,其主要目的是有效地管理和jvzquC41o0€icwl{wg4dqv4tgcjcqxp134;59@<5164ivvq
4.数据库基础数据库学习入门数据库基础 学习数据库是一个从理论到实践、逐步深入的过程,核心是掌握“数据存储逻辑”“查询语言”“设计思想”和“工程应用”四大模块。以下是一套系统、可落地的学习路径,适用于零基础或有基础但想体系化提升的学习者。 一、入门准备:明确核心概念,搭建知识框架jvzquC41dnuh0lxfp0tfv87723e:3;9324:0c{ykenk0fnyckny03>65;8946
5.入门级数据库操作:从基础到实践数据库系统是信息社会不可或缺的一部分,它们为我们提供了快速、准确、高效的信息处理能力。在下一章,我们将学习创建数据库的基本方法。 2. 创建数据库语句实现 在深入探讨如何创建数据库之前,让我们先了解SQL语言的基础知识,这将帮助我们更好地理解数据库操作的原理和背景。 2.1 SQL语言简介 2.1.1 SQL语言的特点和作用 jvzquC41dnuh0lxfp0tfv8|gkzooa<:::8<488ftvkimg8igvcomu86698?28?5
6.neo4j教程本教程将教你Neo4j的基础知识,Java与Neo4j和Spring DATA与Neo4j。 本教程分为Neo4j简介,Neo4j CQL,Neo4j CQL函数,Neo4j管理员,Neo4j与Java和Neo4j与Spring数据框架。 每个部分都包含相关的主题和简单有用的例子。 手册说明 Neo4j是一个世界领先的开源的基于图的数据库。 它是使用Java语言完全开发的。本教程将教你Neo4jvzquC41yy}/y
7.传奇所有引擎数据库SQLite和Navicat的基础使用知识SQLite介绍:SQLite是一款轻型的数据库,属于一个嵌入式的数据库,不需要依赖任何服务就能使用,所以能支持jvzquC41yy}/ivgdm0ipo8yjtgge/<79;3<.3660jvsm
8.postgreSQL数据库基本概念教程PostgreSQL数据库基础知识DB、DBMS将大量数据保存起来,通过计算机加工而成的,可进行高效访问的数据集合称为数据库。DB(Database)管理数据库的计算机系统,统称数据库管理系统(DBMS)为什么要使用DBMS而不是Excel管理数据:无法多人共享数据。某个用户打开该文件,其他用户无法编辑。 无法提供操作大量数据所需格式。要瞬间获取大量数据,jvzquC41yy}/lk:30pku1jwvkerf1;9624:/j}r
9.MYSQL入门学习教程(非常详细),零基础入门到精通,收藏这一篇就够了综上所述,数据库是现代信息化社会不可或缺的基础设施之一,对于提高数据处理效率、保障数据安全、支持业务决策等方面具有重要作用。 2.Mysql数据库简介 (1)特点 开源免费:MySQL是一个开源项目,其源代码可以免费获取,并根据GNU通用公共许可证(GPL)进行分发。这使得MySQL成为许多开发者和企业的首选数据库解决方案。 jvzquC41dnuh0lxfp0tfv8r2a9786>77:1gsvrhng1jfvjnnu175;?;467>