WPF使用
一
WPF界面布局
首先会看到一个靓丽的小方框,将鼠标放在方框的边缘点击就会产生相应的分割线。
现在我们要做的内容需要将窗体分成三行,可以先随便分割一下,以后在调整相互的大小。这时候会注意到下方的XML代码区域。每个R owDefinition作为一个行被定义出来
会使控件在一定的坐标上固定位置以下WPF中的布局观(Layout Phil osophy):
在WPF窗体中,一个窗体只能持有一个控件,当多个控件想要在窗体中展现时,就需要首先设置一个容器控件(Container)
然后将其他控件放到这个控件里面,形成树状结构
因此,布局观第一条就是,控件的布局应该有容器来决定
而不是通过自身使用margin之类的东西来控制位置。
因为这些属性原本应该是控制自己内部展现或与邻里之间关系的;
第二条,控件应避免明确的定义具体的尺寸,因为显示器分辨率及windows窗体的大小都有可能随时改变
通过MinWidth,MinHeight,MaxWidth,MaxHeight属性可以实现这一点
第三条,不要将界面元素位置设置成与屏幕坐标相关.
现在显示器分辨率比较多样话(800×600、1024×768,我的显示器是一台是1400×1050,还有一个是1024×1280竖式的),这样的做法还是比较有风险的。
第四条,容器应将有效空间共享给其子控件,这也是为了不在窗体调整后,遗留出大块的空余。
第五条,容器嵌套使用,因为不同的容器,表现效果不同,必要时应结合使用。
接下来在工具箱(Tool Box)中双击ListView,一个小框会出现在界面上。
接下来在工具箱(Tool Box)中双击WrapPanel,又一个大框会出现在界面上。
再增加一个Button。
最终结果如下:
1)介绍以下容器控件Panel,现在界面中有两个容器型的控件一个是Grid跟元素,另一个是WrapPanel。它们都是容器型控件,不过表现上有所不同。
Grid顾名思义“网格”,在之前我们已经定义了三行高度分辨是*,Au to,22,其实还可以功过ColumnDefinition定义多个列,他的子控件被放在一个一个实现定义好的小格子里面,整齐配列。
而WrapPanel则是将各个控件按照行或列的顺序摞列,当长度或高度不够是就会自动调整换例或行。
还有一个常用控件这里稍后会用到StackPanel,将控件按照行或列来顺序排列不会回行。
2)大家应该注意到了在WrapPanel及Button上面的Grid.Row=" n",这个就是Attached Properties(不知道怎么翻译了,可能叫‘附着属性’).
用来设置WrapPanel及Button应该在父容器的什么位置。这是WPF的特性之一,通俗的理解起来就是,别人有的属性,由于你跟他产生了关系所以你也有了这个属于他的属性。
记得FantasiaX‘水之真谛’曾经给我通俗的解释过这个特性,这里照搬出来分享给大家:一个小学生,身高、体重是他的自身属性,而这个小学生由于是N年级的X班的学生.
因此,这个小学生又带有了一个附加的属性,N年级X班。在这个例子里如果学校作为一个Grid容器,N年级X班可以看作一个小格子,小学生是其中的一个实例,那么,小学生因为安置在这个班级.
因此获得了这个班级所拥有的这个属性,当学期末,老师说,这个学生已经升到N+1年级X班时,这个学生以后就跑到另一个小格子里去上课了。
Attached Properties的XAML用法就是在自己的属性设置地方直接使用容器的类型名称.容器属性名称(Grid.Row)设置对应的值。
3)大家应该注意到类似与ListView.View及Grid.RowDefinitio ns用法,这个叫做Complex Properties(应该叫‘复杂属性’吧).
其实就是元素的某一个属性由于不能够简单的用名值对实现,因此需要单独标签话声明一下。
4)再有就是x:Name="gridView1"这种用法,叫做Markup Exten sions(‘标记扩展’吧),这个可是一个满不错的特性.
由于后面代码中要使用到GridView对象,然而GridView对象有没有N ame属性,如果后台代码想要调用他的话就不得不从父容器向下遍历来找到想要的对象,这样无疑增加了后台代码与前台界面之间的耦合度,试想如果那天突然有需求说要把这个对象从这里移到另一个容器上去.
那么界面的变动伴随着的就是后台代码的一起变动,这与视图/逻辑分离显然背道而驰,有了Markup Extensions.
我们想定位一个没有名字属性的控件,直接为扩展一个名称出来,这个可太方便了(当然,Markup Extensions不只是用来扩展名称的)。
如果希望每个TextBlock和TextBox成为一对出现的话,应该如何呢?
自然是需要一个容器将他们组织起来.
同时,希望他们在一条线上不回行。这就用到了,我们前面说到的一个容器StackPanel。组织后的代码如下:
这样情况下在试试就可以看到效果了,无论窗体边缘怎么托拉Tex tBlock和TextBox总是成对的.
同时,随着窗体的拖动,控件会不断的改变位置一适应最小原则(如果想要让他固定下来的话.
那就需要将WrapPanel换成其他的Panel就可以了)。如下图所示:
public Window2()
{
InitializeComponent();
getData();
}
SqlDataAdapter sda;
DataTable dt;
void getData()
{
//init sqlconnection
SqlConnectionStringBuilder connbuilder=new SqlConn ectionStringBuilder();
connbuilder.DataSource="(local)";
connbuilder.IntegratedSecurity=true;
connbuilder.InitialCatalog="AdventureWorks";
//start to make sql query
SqlConnection conn=new SqlConnection(connbuilder.C onnectionString);
sda=new SqlDataAdapter("select ContactID,FirstName, LastName,EmailAddress from person.contact where ContactID<=100;",conn);
SqlCommandBuilder commbuilder=new SqlCommandBuilde r(sda);
sda.UpdateCommand=commbuilder.GetUpdateCommand();
dt=new DataTable();
sda.AcceptChangesDuringUpdate=true;
sda.Fill(dt);
}
private void button1_Click(object sender,RoutedEventArgs e)
{
getData();
}
WPF前台界面与后台数据的Binding
Binding这个此翻译起来有争议,为了避免误导大家,因此我还是不写成中文了。
好了!接下来终于到最精彩的地方了。各位读者们一会会为后面所发生的事情而感到震惊的,一切就是这样的完成了……
1)为ListView控件指
明数据源,通过ItemSourc
e属性设置,这一部分需要
通过代码来实现(目前位置
还不知道如何通过XAML语
言来实现,哪位大哥可以指
点一下)。
在void getData()方法
的结尾处增加一行代码“l
istView1.ItemsSource=
dt.DefaultView;”
2)给GridViewColumn指明当前列对应于数据源的哪一项,可以通过DisplayMemberBinding属性来实现.
其中的值便是上一步中指明的数据源dt.DefaultView的每一个数据项的名称.