代码改变世界

wpf控件开发基础(1)

2008-07-03 21:44 by Clingingboy, ... 阅读, ... 评论, 收藏, 编辑

        从现在开始,我将尝试写有关wpf控件开发相关的知识,把文章这对我来说很难,所以这个系列的文章在时间跨度上可能会拖的比较长。我希望我介绍是比较详细的,而不仅仅是一个简单的控件开发流程。我是一个真正的Web开发人员,很少尝试编写客户端程序,之所以开发wpf,一方面是项目的需要,另一方面则是wpf的xaml编程的标签化,使得像我这样的web开发人员很容易接受,去尝试,大家学习当中可以与web控件开发进行比较。

一.画一个椭圆 

我们该从哪里开始?我们从显示开始。使用wpf,可以很容易的就创建一个图形,比如一个椭圆

<Ellipse Margin="34,45,44,117" Name="ellipse1" Stroke="Black" Fill="Red" />


图一

 二.定义控件的样式
上面的Ellipse似乎与控件无关,但却是控件的组成部分.我们再来定义一个我们非常熟悉的Label控件,此控件会在界面上显示"hello"字符串.
<Label Content="hello"></Label>

接下来我需要Label控件的背景以Ellipse来显示,可以使用wpf的样式和模板来重新定制外观,代码如下

Code

效果与图一相同,我们似乎忘了把Content属性的内容显示出来,所以我们还要借助一个控件把Content显示出来.
使用TextBlock?不行,它的Text属性是不折不扣的String类型,那么我们使用Label控件来绑定Content,代码如下
(之前的上下文代码省略)
<Ellipse Margin="34,45,44,117" Fill="{TemplateBinding Background}"/>
<Label Content="{TemplateBinding Content}"></Label>

重新编译下,似乎并未通过,那我们使用ContentControl控件吧
<ContentControl Content="{TemplateBinding Content}"></ContentControl>

效果如图,效果是显示出来了.

三.显示控件的内容

ContentControl在实际中可能很少使用,但却很重要,这便是我引出的话题.我们来看下Label控件的父类,就是ContentControl,为什么不是Control类?
如Label控件的Content属性其实是由ContentControl类定义的,目的是为了将Content的内容显示在wpf窗体。那没有了ConentControl类,我们就不能将内容显示在wpf窗体上了吗?或者问ContentControl类的Content是如何显示在wpf窗体上的呢?
这里我们就需要知道ContentPresenter类的作用,ContentPresenter的作用就是显示内容,但Control类没有这个Content属性,所以在Control类之上写了一个ContentControl类,然后ContentPresenter(其显示依赖于ContentControl类)负责将ContentControl的Content属性显示出来。每个控件都有一个默认的ContentPresenter用于显示Content内容,我们称这种控件为内容控件。所以上面的示例的样式最终代码如下
    <Grid>
        
<Grid.Resources>
            
<Style TargetType="Label">
                
<Setter Property="Template">
                    
<Setter.Value>
                        
<ControlTemplate TargetType="Label">
                            
<Grid>
                                
<Ellipse Margin="34,45,44,117" Fill="{TemplateBinding Background}"/>
                                
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center"
                            VerticalAlignment
="Center"/>
                            
</Grid>
                        
</ControlTemplate>
                    
</Setter.Value>
                
</Setter>
            
</Style>
        
</Grid.Resources>
        
<Label Background="Red" Content="hello wpf control"></Label>
    
</Grid>

在继承Control类的情况下,你同样可以使用ContentPresenter类,不过你需要自己准备一个属性与其Content属性绑定。

如果看了上面的解释不理解的话,我们下面可以通过一个很好的范例来理解这一点。

MasterPage示例(本示例来codeproject)

这是一篇非常好的文章
wpf没有MasterPage这一概念,通常框架会使用一个容器来加载一个模块,作者利用wpf的模板和ContentPresenter很好的展示了这一技术
其定义了一个MasterPage类,然后定义了三个属性,再以ContentPresenter来显示这三个属性内部的内容.

总结一下
1.如Ellipse是为了在模板中装饰控件外观,可以通过控件的属性与其属性绑定来美化控件
2.ContentPresenter用于显示控件的ContentControl的Content属性

So 控件=外观+内容
好了,本文结束