WPF入门_树形结构与XAML对象属性赋值_2021-06-11

1. 浅析WPF用户界面的树形结构

用户界面即User Interface, 应用程序面向普通使用者的界面, 应用程序和人/交互打交道的部分.
常用的用户界面有DOS用户界面(如控制台应用程序), 图形用户界面(如各种桌面应用, 如浏览器, VS, QQ...).
图形用户界面属于用户友好型界面.

WPF树形结构与Winform等平面结构的异同:

  1. 其他平面布局:
    窗体即画布, 所有控件均在同一个平面上, 不存在谁包含谁, 各控件为平级关系.
  2. WPF树形布局:
    XML本身即为一种树形结构, XAML为其变种, 各控件既可以互相独立, 也可以互相嵌套(个别限制情况除外), 选择更多, 布局更加灵活. 示例如图1-2:
    WPF入门_树形结构与XAML对象属性赋值_2021-06-11
图1-1
![](https://www.icode9.com/i/l/?n=20&i=blog/1242007/202106/1242007-20210611225345106-1247560233.png)
图1-2

2. 在XAML中对用户属性赋值

XAML中的每一组标签都将被XAML编译器创建一个对象(对象, 而非变量). 如上图1-2中XAML编译器会Window, Grid, TextBox*4, Button几个控件编译为对象.
对象有字段有属性, 一般将属性对外暴露供外界使用/查看, 字段不够安全, 仅用来存储数据, 且不具有校验数据的功能.

形式1, Attribute=Value型
形式2, 属性标签
形式3, 标签扩展

形式1, Attribute=Value型

  • 简单易懂, 但难以绘制复杂图形
  • 值只能是字符串形式
    形如HelloNerd.MainWindow.xaml中:
<Window x:Class="HelloNerd.MainWindow"
    ...
    <!--Attribute=Value, 如Height="450"等-->
    Title="MainWindow" Height="450" Width="800"
    WindowStartupLocation="CenterScreen">
    <!--使用广泛, 但一般只能使用在比较简单的地方, Path标签已经几乎是attribute=value形式可绘制的最复杂的图形-->
    <!--复杂线形, M形式, 从(0,0)点开始, L直线线形画到(100,200)点, 再L线形画到(100,200)点, Z命令指令闭合. Stroke路径 颜色, Fill填充色-->
    <Path Data="M 0,0 L 200,100 L 100,200 Z" Stroke="Black" Fill="Red">
</Window>

HelloNerd.Models.Human类中

//将自定义类型转换器以特性的形式附加到Human类上
[TypeConverterAttribute(typeof(NameToHumanTypeConverter))]
public class Human
{
    public string Name { get; set; }
    public Human Child { get; set; }
}
/// <summary>
/// 自定义类型转换器
/// </summary>
public class NameToHumanTypeConverter: TypeConverter
{
    public override object ConvertFrom(
        ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        //value即传递来的"Mikeson"字符串
        string name = value.ToString();
        Human child = new Human();
        child.Name = name;
        //return base.ConvertFrom(context, culture, value);原始自动生成的return语句
        return child;
    }
}

HelloNerd.MainWindow.xaml中:

<Window x:Class="HelloNerd.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:comment1="引入当前程序集, 当前程序集一般命名为local"
        xmlns:local="clr-namespace:HelloNerd"
        xmlns:comment2="引入Models命名空间"
        xmlns:models="clr-namespace:HelloNerd.Models"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        WindowStartupLocation="CenterScreen">
    <!--每个wpf程序以资源字典形式维护着一系列的资源-->
    <!--将Human作为Windows资源声明出来-->
    <Window.Resources>
        <!--如需为Child对象属性赋值, 需要更复杂操作, 如为它的Child对象属性赋值, 指定自定义TypeConverter进行数据类型转换-->
        <models:Human x:Key="human" Name="Mike" Child="Mikeson"/>
    </Window.Resources>
    <Grid>
        <!--Click指定事件处理函数-->
        <Button Content="show" Click="ShowName"></Button>
    </Grid>
</Window>

HelloNerd.MainWindow.xaml.cs中:

private void ShowName(object sender, RoutedEventArgs e)
{
    //第一步, 将Windows资源检索出来
    //调用窗体自己的FindResource方法, 找到名为human的资源
    //尝试转换为Human类型, 用as转换时如为null则返回null
    Human human = this.FindResource("human") as Human;
    if (human != null)//(human is not null) 类似 
    {
        MessageBox.Show(human.Name+"'s son is "+human.Child.Name);
    }
}

形式2, 标签属性型

  • 便于绘制复杂图形
  • 便于图形对象的嵌套
  • 可能使程序更加复杂, 能使用形式1(attr=val)的尽量使用形式1
    例一, 按钮中嵌套一个正方形:
<Grid>
    <Button Width="100" Height="100">
        <Button.Content >
            <!--Button.Content也是一个标签, 通过"对象类名.对象的属性名"构成, 
            这种标签的内容就是你需要的复杂对象属性的内容. 
            其意义在于为本Button对象的Content属性赋予复杂对象值(如嵌套画出复杂图形, 按钮里画了个正方形之类的)-->
            <Rectangle Width="50" Height="50" Stroke="Blue" Fill="Yellow"/>
        </Button.Content>
    </Button>
</Grid>

WPF入门_树形结构与XAML对象属性赋值_2021-06-11

例二, 使用渐变色填充矩形, 简单笔刷已经无法满足, 需要指定笔刷

<Grid>
    <Rectangle Width="200" Height="200" Stroke="Yellow">
        <Rectangle.Fill>
            <!--将Fill属性指定为渐变笔刷-->
            <LinearGradientBrush>
                <!--为笔刷设定起点终点, X/Y为相对位置-->
                <LinearGradientBrush.StartPoint>
                    <Point X="0" Y="0"></Point>
                </LinearGradientBrush.StartPoint>
                <LinearGradientBrush.EndPoint>
                    <Point X="1" Y="1"/>
                </LinearGradientBrush.EndPoint>
                <!--为渐变笔刷设定色彩-->
                <LinearGradientBrush.GradientStops>
                    <!--设定渐变色彩集合, 可以有多个色彩-->
                    <GradientStopCollection>
                        <!--前20%为红色, 中间60%为绿色, 最后20%为蓝色-->
                        <GradientStop Offset="0.3" Color="Red"/>
                        <GradientStop Offset="0.5" Color="Yellow"/>
                        <GradientStop Offset="0.2"  Color="Blue"/>
                    </GradientStopCollection>
                </LinearGradientBrush.GradientStops>
            </LinearGradientBrush>
        </Rectangle.Fill>
    </Rectangle>
</Grid>

WPF入门_树形结构与XAML对象属性赋值_2021-06-11

上一篇:C#实习第五天——初学WPF


下一篇:C#复习