深入浅出笔记_在XAML中为对象赋值

XAML赋值浅析

XAML语言是一种声明性语言 也就是说,你每见到一个标签,我们的XAML编译器就会为我们创建一个相应的对象
如下 XAML编译器就为我们创建了两个对象(不是变量是对象!)

<Window x:Class="WPF_MVVMXueXiBiJi.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:WPF_MVVMXueXiBiJi"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        
    </Grid>
</Window>

我们都知道对象用来存储数据的地方有两个地方

  1. 字段
  2. 属性

而向外暴露的都是属性向外暴露,因为字段不够安全,字段只能单纯的存储数据,并不具有对数据进行校验的功能
比如说我有人这个类,人都有年龄,而如果我使用字段向外暴露数据的话,那么这个字段就完全有可能被赋值为1000,但人的年龄不可能为一千,
而我们使用属性向外暴漏的话,我们就可以在属性的set这个语句里面对传进来的数值进行检验,如果过大或过小,就抛出异常,不让有问题的数据污染我们的程序

上面编译器为我们创建的Window ,Grid对象也具有很多属性,而在XAML里面我们有三种方法为对象的属性赋值

Atttribute=Value方式为对象属性赋值

实例: 我们使用Atttribute=Value的方式,将Window对象的Title这个属性赋值了MainWindow,Height属性赋值了450 ,Width属性赋值了800

<Window x:Class="WPF_MVVMXueXiBiJi.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:WPF_MVVMXueXiBiJi"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        
    </Grid>
</Window>

代码效果:
如图 Window的Title是MainWindow,高是450,width是800
在这里插入图片描述
Atttribute=Value赋值方式还有复杂一点的
实例: 给Path 对象的Data属性赋值,起点M位置为X:0 Y:0 L用直线 画到X:200,Y:200,L用直线画到X:100,Y200,Z闭合,这是Atttribute=Value赋值方式最复杂的了,如果需要赋的值再复杂就需要使用使用属性标签的方式了

<Window x:Class="WPF_MVVMXueXiBiJi.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:WPF_MVVMXueXiBiJi"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Path Data="M 0,0 L 200,200 L 100,200 Z" Stroke="Aqua"></Path>
    </Grid>
</Window>

实现效果在这里插入图片描述

为什么非字符串类型的属性能使用Atttribute=Value赋值方式为其赋值

如果你仔细观察的话,你就能发现,Atttribute=Value赋值方式所赋的值都是字符串类型的值,但这个属性并不是string类型的属性,如刚刚上面使用Atttribute=Value赋值方式赋值的Data属性它是Geometry类型的属性,但是我们使用Atttribute=Value赋值方式所赋的值的类型是string类型
那它们是怎么映射过来的呢?
下面通过一个例子来讲解
实现先在后台代码生成一个Human类,类里面有两个属性,string类型的Name ,和Human类型的Child,
很显然,如果一个Human具有Child 属性,那么Child 属性也具有自己的Name属性

  public class Human
    {
        public string Name { set; get; }
        public Human Child { get; set; }
    }

然后在XAML代码里使用标签声明一个Human对象
我们首先需要使用硬编码将刚刚声明的Human类所在的 WPF_MVVMXueXiBiJi 命名空间引入进来

xmlns:local="clr-namespace:WPF_MVVMXueXiBiJi"
一般情况下把当前程序集包含的命名空间映射为local,当然,这个映射名爱咋取名咋取名,只是叫local的话意义比较明确

引入好了命名空间之后我们就可以为Human类声明对象了
我们先将Human作为资源声明出来,代码如下

 <Window.Resources>
      <local:Human x:Key="Human"  Name="Tim"></local:Human>
 </Window.Resources>

然后声明一个Button按钮并让我们点击按钮的时候弹出弹窗显示Human的属性
声明按钮

<Button Content="show!" Width="100" Height="50" Click="Button_Click"></Button>

后台Click事件逻辑部分
this.FindResource(“Human”)调用窗体自己的FindResource方法获得Key值为Human的对象
is Human human判断FindResource方法获得是否是Human类型
如果是则弹出human的Name属性

 private void Button_Click(object sender, RoutedEventArgs e)
 {
      if (this.FindResource("Human") is Human human)
      {
          MessageBox.Show(human.Name);
      }
      return;
  }

效果
点击show后弹出窗弹出了human对象的name
在这里插入图片描述
这个很简单,因为Huamn类的Name属性本来就是字符串类型,那如果我们使用Atttribute=Value赋值方式给Huamn类的Child属性赋值呢?它能不能将赋值给Child属性的字符串转换为Child的Name属性?(Child属性是Huamn类型)
如下,如果它足够智能的话,它会转化Child类型并将赋值给他的字符串转化为Child的Name属性
前台XAML属性

<local:Human x:Key="Human"  Name="Tim" Child="Little Tim"></local:Human>

点击Show按钮后,抛出异常
在这里插入图片描述
它的意思是不能使用Atttribute=Value赋值方式将字符串赋值给Human类型的Child属性
但是我们明明在前面使用Atttribute=Value赋值方式给Geometry类型的Data属性赋值了,
这个时候就需要使用类型转换了
首先声明一个类让他派生自TypeConverter并重写他里面的ConvertFrom方法

 public class NameToHumanTypeConverter : TypeConverter
    {
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            string name = value.ToString();
            Human child = new Human();
            child.Name = name;
            return child;
        }
    }

声明完这个类之后将它作为特性,附加至Human这个类上面去

	 [TypeConverterAttribute(typeof(NameToHumanTypeConverter))]
	 public class Human
	 {
	     public string Name { set; get; }
	     public Human Child { get; set; }
	 }

再改一下button的点击事件,现在不show Human的Name了show Child的Name

	private void Button_Click(object sender, RoutedEventArgs e)
	{
	     if (FindResource("Human") is Human human)
	     {
	         MessageBox.Show(human.Child.Name);
	     }
	     return;
	 }

效果图
在这里插入图片描述
好了,现在我们就使用Atttribute=Value赋值方式将字符串赋值给Human类型的Child属性了,

属性标签方式赋值

XAML标签是用来声明对象的,而属性标签并不用来声明对象,而是对应着对象的属性
实例如下

	<Button Width="100" Height="50" Click="Button_Click">
	    <Button.Content>
	        <Rectangle Width="20" Height="20" Stroke="DarkGreen" Fill="LawnGreen"></Rectangle>
	    </Button.Content>
	</Button>

效果图
在这里插入图片描述
还有复杂一点的

<Rectangle Width="200" Height="200" Stroke="Blue">
            <Rectangle.Fill>
                <LinearGradientBrush>
                    <LinearGradientBrush.StartPoint>
                        <Point X="0" Y="0"/>
                    </LinearGradientBrush.StartPoint>
                    <LinearGradientBrush.EndPoint>
                        <Point X="1" Y="1"/>
                    </LinearGradientBrush.EndPoint>
                    <LinearGradientBrush.GradientStops>
                        <GradientStopCollection>
                            <GradientStop Offset="0.2" Color="LightBlue"></GradientStop>
                            <GradientStop Offset="0.7" Color="DarkBlue"></GradientStop>
                            <GradientStop Offset="1.0" Color="Blue"></GradientStop>
                        </GradientStopCollection>
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

效果图
在这里插入图片描述

标签拓展

使用标记扩展轻松实现XAML页面属性赋值,资源引用,类型转换等操作。
常用的标记扩展:

  1. Binding ——> XAML载入时,将数据绑定到XAML对象;
  2. StaticResorce ——> 引用数据字典中定义的静态资源;
  3. TemplateBinding ——> XAML页面中对象模板绑定调用;
  4. RelativeSource ——> 对特定数据源引用;

运用与属性:

ElementName

  1. ElementName
    在这里插入图片描述

  2. Path
    在这里插入图片描述

实际运用:

<StackPanel>
        <Button x:Name="Test" Width="100" Height="61.8" VerticalAlignment="Bottom" Background="SkyBlue"></Button>
        <Border Margin="10" BorderBrush="Black" BorderThickness="1"></Border>
        <Button Content="binding测试"
                Height="61.8"
                VerticalAlignment="Top"
                Background="{Binding ElementName=Test,Path=Background}"
                Width="{Binding ElementName=Test,Path=Width}"></Button>
    </StackPanel>

因为第二个按钮的属性“Background”和“Width”的值都获取要用作绑定第一个按钮为源对象,所以第二个按钮的属性“Background”和“Width”的值直接继承第一个按钮的这两个属性的值:
在这里插入图片描述

StaticResorce

StaticResorce:控件需要通过StaticResorce引用在窗口中自定义的静态资源
在这里插入图片描述

因为资源样式中设置的是背景颜色“Background”,所以在Binding的作用下第二个按钮的“Background”属性值也会随之改变:
在这里插入图片描述

TemplateBinding:

在这里插入图片描述

代码

在这里插入图片描述
自定义视觉树,利用TemplateBinding实现图标按钮:
在这里插入图片描述

RelativeSource:

RelativeSource:实现标记扩展,以描述绑定源相对于绑定目标的位置。
在这里插入图片描述
代码
在这里插入图片描述
实现效果
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Qayrup

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值