WPF中文网

Control基类

Control是许多控件的基类。比如最常见的按钮(Button)、单选(RadioButton)、复选(CheckBox)、文本框(TextBox)、ListBox、DataGrid、日期控件等等。这些控件通常用于展示程序的数据或获取用户输入的数据,我们可以将这一类型的控件称为内容控件或数据控件,它们与前面的布局控件有一定的区别,布局控件更专注于界面,而内容控件更专注于数据(业务)。

Control类虽然可以实例化,但是在界面上是不会有任何显示的。只有那些继承了Control的子类(控件)才会在界面上显示,而且所呈现的样子各不相同,为什么会是这样呢?

因为Control类提供了一个控件模板(ControlTemplate),而几乎所有的子类都对这个ControlTemplate进行了各自的实现,所以在呈现子类时,我们才会看到Button拥有Button的样子,TextBox拥有TextBox的样子。

Control基类说

我给你们一张白纸(ControlTemplate),你们可以在上面想画什么就画什么

我们在这一章节并不对模板(Template)进行详细的介绍,只是先阐述模板的概念,接下来,我们先将目光聚焦到Control的结构定义:

public class Control : FrameworkElement
{
public static readonly DependencyProperty BorderBrushProperty;
public static readonly RoutedEvent PreviewMouseDoubleClickEvent;
public static readonly DependencyProperty TemplateProperty;
public static readonly DependencyProperty PaddingProperty;
public static readonly DependencyProperty IsTabStopProperty;
public static readonly DependencyProperty TabIndexProperty;
public static readonly DependencyProperty VerticalContentAlignmentProperty;
public static readonly DependencyProperty HorizontalContentAlignmentProperty;
public static readonly RoutedEvent MouseDoubleClickEvent;
public static readonly DependencyProperty FontStyleProperty;
public static readonly DependencyProperty FontStretchProperty;
public static readonly DependencyProperty FontSizeProperty;
public static readonly DependencyProperty FontFamilyProperty;
public static readonly DependencyProperty ForegroundProperty;
public static readonly DependencyProperty BackgroundProperty;
public static readonly DependencyProperty BorderThicknessProperty;
public static readonly DependencyProperty FontWeightProperty;

public Control();

public FontStyle FontStyle { get; set; }
public FontStretch FontStretch { get; set; }
public double FontSize { get; set; }
public FontFamily FontFamily { get; set; }
public Brush Foreground { get; set; }
public Brush Background { get; set; }
public Thickness BorderThickness { get; set; }
public bool IsTabStop { get; set; }
public VerticalAlignment VerticalContentAlignment { get; set; }
public int TabIndex { get; set; }
public Thickness Padding { get; set; }
public ControlTemplate Template { get; set; }
public FontWeight FontWeight { get; set; }
public Brush BorderBrush { get; set; }
public HorizontalAlignment HorizontalContentAlignment { get; set; }
protected internal virtual bool HandlesScrolling { get; }

public event MouseButtonEventHandler MouseDoubleClick;
public event MouseButtonEventHandler PreviewMouseDoubleClick;

public override string ToString();
protected override Size ArrangeOverride(Size arrangeBounds);
protected override Size MeasureOverride(Size constraint);
protected virtual void OnMouseDoubleClick(MouseButtonEventArgs e);
protected virtual void OnPreviewMouseDoubleClick(MouseButtonEventArgs e);
protected virtual void OnTemplateChanged(ControlTemplate oldTemplate, ControlTemplate newTemplate);

}

我们先来看看Control基类为它的子类们提供了哪些属性

属性说明
FontStyle获取或设置控件的字体结构,类似于Word中字体的常规、斜体或倾斜
FontStretch获取或设置紧缩或在屏幕上展开一种字体的程度。
FontSize获取或设置字体大小。
FontFamily获取或设置控件的字体系列。如:微软雅黑 = "Microsoft YaHei UI"
Foreground获取或设置控件的字体颜色,也就是所谓的前景色画笔,它是一个刷子(Brush)
Background获取或设置一个用于描述控件的背景画笔。
BorderThickness获取或设置控件的边框宽度。
IsTabStop获取或设置一个值,该值指示控件是否包括在选项卡上的导航窗格中。
VerticalContentAlignment获取或设置控件的内容的垂直对齐方式。
TabIndex获取或设置一个值,确定当用户导航控件通过使用 TAB 键元素接收焦点的顺序。
Padding获取或设置在控件中的填充量。
Template获取或设置控件模板。
FontWeight获取或设置指定的字体粗细。
BorderBrush获取或设置一个用于描述一个控件的边框背景画笔。
HorizontalContentAlignment获取或设置控件的内容的水平对齐方式。

大部分的属性都比较好理解,这里着重介绍一下Template属性。如果把人比作是一个Control(控件),那么”着装“就是Template(模板)。在大街上,我们会看到不同着装的人来来往往。

所以Control的Template定义了控件的外观(着装)。

数据模板

与控件模板类似的,还有一个概念叫数据模板。形象地说,还是把人比作控件,那么人体的五脏六腑就是这个控件的数据,而五脏六腑(数据)的外观就是指数据模板。

我们来看一个实际的例子

<Window x:Class="HelloWorld.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:HelloWorld"
        mc:Ignorable="d"
        Title="HelloWorld - www.wpfsoft.com" Height="350" Width="500">
    <Control Margin="10">
        
    </Control>

</Window>

我们在Window窗体中实例化了一个Control类,但是,界面上空无一物。这是因为当前这个Control对象还没有”穿衣服“,也就是说,它的Template并没有内容,实际上,此刻Template属性等于null。

那我们尝试给他穿一件衣服吧。

<Window x:Class="HelloWorld.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:HelloWorld"
        mc:Ignorable="d"
        Title="HelloWorld - www.wpfsoft.com" Height="350" Width="500">
    <Control Margin="10">
        <Control.Template>
            <ControlTemplate TargetType="Control">
                <Border Background="LightBlue">
                    <TextBlock Text="WPF中文网" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Control.Template>
    </Control>
</Window>

我们为Control的Template实例化了一个ControlTemplate对象,并在这个对象中增加了一个Border,在Border中又增加了一个TextBlock子元素,于是Control就有了这样一件新衣服。

在这里,我们要明白一个要点是,Control类的Template属性是ControlTemplate类型的。所以上面的代码才必须这样写才可以。而ControlTemplate又是什么东东?为什么在xaml中实例化时,后面要跟一句TargetType="Control"?关于这一点,我们将在后面专门拿一章节来阐述ControlTemplate以及它的父类。

事件

在这一小节里,您只要能明白Template的概念就行了。除了这个属性,Control类还提供了两个事件,它们分别是PreviewMouseDoubleClick和MouseDoubleClick。

事件名称说明
PreviewMouseDoubleClick表示鼠标双击或多次单击时触发的事件
MouseDoubleClick表示鼠标双击或多次单击时触发的事件

以Preview开头的事件叫隧道事件或预览事件,而MouseDoubleClick没有以Preview开头,所以它叫冒泡事件。

WPF的前端代码其实是一棵树,当我们在某个目标控件上进行鼠标操作时,所引发的事件有两个方向,一是从Winow根节点一直路由到目标控件上,看起来就好像是从外面一直沿着这棵树路由引发至里面,这就像我们开车进入隧道一样,所以Preview开头的事件叫隧道事件。

冒泡事件事件的路由方向相反,是从目标控件位置开始,一直路由引发至最外层的Window窗体。

关于路由事件,我们会在后面拿一章节专门讲解,这里只提一下这个概念。

通常,我们并不会直接实例化Control基类,确实这样做对我们实际帮助不大,我们要使用的——是它膝下各个子控件,而在这众多的子控件中,Button是最常见最简单的控件了。不过,Button的基类是ButtonBase,ButtonBase的基类是ContentControl,ContentControl的基类是Control。如果我们要探讨Button控件,看样子必须要先介绍一下ContentControl基类和ButtonBase基类才行了。

当前课程源码下载:(注明:本站所有源代码请按标题搜索)

文件名:015-《Control基类》-源代码
链接:https://pan.baidu.com/s/1yu-q4tUtl0poLVgmcMfgBA
提取码:wpff

——重庆教主 2023年8月22日

copyright @重庆教主 WPF中文网 联系站长:(QQ)23611316 (微信)movieclip (QQ群).NET小白课堂:864486030 | 本文由WPF中文网原创发布,谢绝转载 渝ICP备2023009518号-1