WPF2-1在xaml为对象的属性赋值.md

  • [1. Attribute=Value方式](#1. Attribute=Value方式)
    • [1.1. 简单属性赋值](#1.1. 简单属性赋值)
    • [1.2. 对象属性赋值](#1.2. 对象属性赋值)
  • [2. 属性标签的方式给属性赋值](#2. 属性标签的方式给属性赋值)
  • [3. 标签扩展 (Markup Extensions)](#3. 标签扩展 (Markup Extensions))
    • [3.1. StaticResource](#3.1. StaticResource)
    • [3.2. Binding](#3.2. Binding)
      • [3.2.1. 普通 Binding](#3.2.1. 普通 Binding)
      • [3.2.2. ElementName Binding](#3.2.2. ElementName Binding)
      • [3.2.3. RelativeSource Binding](#3.2.3. RelativeSource Binding)
      • [3.2.4. StaticResource Binding (带参数的 Binding)](#3.2.4. StaticResource Binding (带参数的 Binding))
      • [3.2.5. TemplateBinding](#3.2.5. TemplateBinding)
    • [3.3. 标签扩展总结:](#3.3. 标签扩展总结:)
    • [3.4. 标签扩展注意:](#3.4. 标签扩展注意:)

1. Attribute=Value方式

1.1. 简单属性赋值

<Grid>

    <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>

上面的代码中Content HorizontalAlignment VerticalAlignment Width Click都是直接复制的方式,但可以看到这种复制最简单,但不能赋太复杂的值。

优点: 赋值方便。

缺点: Value为字符串,但是对象属性未必是字符串,因此无法赋太复杂的值。

1.2. 对象属性赋值

先在cs代码中定义对象Human

public class Human

{

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

然后我们xaml上有个Human对象,并给human对象的Child属性赋值

xaml代码:

<Window x:Class="MyWPFDemo1.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:MyWPFDemo1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
    </Grid>


    <Window.Resources>
        <local:Human x:Key="Human1" Name="小明"/>
    </Window.Resources>
</Window>

cs代码:

namespace MyWPFDemo1

{

    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }


        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Human h = (Human)this.FindResource("Human1");
            MessageBox.Show(h.Name);            
            //MessageBox.Show(h.Name + "的孩子是" + h.Child.Name);            //xaml中没有给child对象赋值,所以直接访问会报错
        }
    }


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

在上面的示例中human类中的属性child没有被赋值,如果赋值为字符串会编译出错,那么只有通过实现typeConverter来进行扩展。

首先,我们要从TypeConverter类派生出自己的类,并重写它的一个ConvertFrom方法。这个方法有一个参数名为value,这个值就是在XAML文档里为它设置的值我们要做的就是把这个值"翻译"成合适类型的值赋给对象的属性:

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


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

这样就可以在xaml中直接对Child属性赋值了,

<Window.Resources>

    <local:Human x:Key="Human1" Name="小明" Child="小小明"/>
</Window.Resources>

2. 属性标签的方式给属性赋值

在XAML中,非空标签均具有自己的内容(Content)。标签的内容指的就是夹在起始标签和结束标签之间的一些子级标签,每个子级标签都是父级标签内容的一个元素(Element),简称为父级标签的一个元素。顾名思义,属性元素指的是某个标签的一个元素对应这个标签的一个属性,即以元素的形式来表达一个实例的属性。代码描述为:

<ClassName>

    <ClassName.PropertyName>
        <!--以对象形式为对象的属性赋值-->
    </ClassName.PropertyName>
</ClassName>

遇到属性是复杂对象时这种语法的优势就体现出来了,如使用线性渐变画刷来填充这个矩形。遇到属性是复杂对象时这种语法的优势就体现出来了,如使用线性渐变画刷来填充这个矩形。

<Grid VerticalAlignment="Center" HorizontalAlignment="Center">

    <Rectangle x:Name="rectangle" Width="200" Height="120">
        <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       Offset="0.7" Color="Blue"/>
                        <GradientStop       Offset="1.0" Color="DarkBlue"/>
                    </GradientStopCollection>
                </LinearGradientBrush.GradientStops>
            </LinearGradientBrush>
        </Rectangle.Fill>
    </Rectangle>
</Grid>

3. 标签扩展 (Markup Extensions)

仔细观察XAML中为对象属性赋值的语法,你会发现大多数赋值都是为属性生成一个新对象。但有时候需要把同一个对象赋值给两个对象的属性,还有的时候需要给对象的属性赋一个null值,WPF甚至允许将一个对象的属性值依赖在其他对象的某个属性上。当需要为对象的属性进行这些特殊类型赋值时就需要使用标记扩展了。

  • 所谓标记扩展,实际上是一种特殊的Attribute=Value语法,其特殊的地方在于Value字符串是由一对花括号及其括起来的内容组成,XAML编译器会对这样的内容做出解析、生成相应的对象。

在 WPF 中,标签扩展 (MarkupExtension) 主要用于提供数据绑定、资源引用等动态功能。对于资源引用和数据绑定,常用的标签扩展有两种主要类型:StaticResourceBinding。而对于这些标签扩展,我们通常会有不同的方式来绑定数据或引用资源。

3.1. StaticResource

StaticResource 是一种标签扩展,用于从资源字典中引用资源。在 XAML 中,StaticResource 通过键名查找静态资源。这是一种在应用启动时就加载并且在整个应用程序生命周期内不会改变的资源引用方式。

xaml 复制代码
<Button Content="{StaticResource MyButtonStyle}" />

3.2. Binding

Binding 标签扩展用于数据绑定,允许将 UI 元素的属性绑定到数据源。数据源可以是任何实现了 INotifyPropertyChanged 接口的对象或其他可绑定的对象。Binding 是数据绑定机制的核心。

Binding 也有多种方式和特性,以下是 5 种常见的绑定方式:

3.2.1. 普通 Binding

最常见的 Binding 方式,通过指定一个数据源和路径来绑定。

xaml 复制代码
<TextBlock Text="{Binding Path=Name}" />

3.2.2. ElementName Binding

将数据绑定到页面中的另一个元素,通过 ElementName 指定源元素。

xaml 复制代码
<TextBlock Text="{Binding Path=Text, ElementName=myTextBox}" />

<TextBox Name="myTextBox" Text="Hello World" />

3.2.3. RelativeSource Binding

使用 RelativeSource 绑定来指定相对于当前元素的上下文,例如父元素或祖先元素。

xaml 复制代码
<TextBlock Text="{Binding Path=Name, RelativeSource={RelativeSource AncestorType=Window}}" />

3.2.4. StaticResource Binding (带参数的 Binding)

通过 Binding 与静态资源配合使用,比如从资源字典中绑定样式或其他资源。

xaml 复制代码
<TextBlock Text="{Binding Source={StaticResource MyResourceKey}}" />

3.2.5. TemplateBinding

TemplateBinding 是一种简化的绑定方式,通常用于控制模板中的元素。它通常用于控件模板中的数据绑定,简化了 Binding 的写法。

xaml 复制代码
<Button Content="{TemplateBinding Button.Content}" />

3.3. 标签扩展总结:

在 WPF 中,常见的 BindingStaticResource 标签扩展包括以下五种主要方式:

StaticResource 用于引用静态资源。

普通 Binding,直接绑定数据源和属性。
ElementName 绑定,绑定到同一页面中的另一个元素。
RelativeSource 绑定,基于元素的相对位置进行绑定。
TemplateBinding,简化控件模板中的绑定。

3.4. 标签扩展注意:

● 标记扩展是可以嵌套的,例如Text="{Binding Source=(StaticResource myDataSource),Path=PersonName)"是正确的语法。

● 标记扩展具有一些简写语法,例如"{Binding Value,....!"与"[Binding Path=Value,...]"是等价的、"(StaticResource myString,....}"与"(StaticResource ResourceKey-myString,....)" 是等价的。两种写法中,前者称为固定位置参数 (Positional Parameter),后者称为具名参数(Named Parameters)。固定位置参数实际上就是标记扩展类构造器的参 数,其位置由构造器参数列表决定。

● 标记扩展类的类名均以单词Extension为后级,在XAML使用它们的时候 Extension 后级可以省略不写,比如写Text-"{x:Static.....}" 与写Text="{x:StaticExtension....}"是等价的。

相关推荐
AI向前看4 分钟前
PHP语言的网络编程
开发语言·后端·golang
涅槃寂雨6 分钟前
C语言小任务——1000以内含有9的数字
c语言·开发语言·算法
绿草在线9 分钟前
JDBC实验测试
java·开发语言
jk_10112 分钟前
MATLAB中characterListPattern函数用法
开发语言·matlab
休息一下接着来28 分钟前
C++ 中的最大值和最小值判断
开发语言·c++·算法
大懒猫软件35 分钟前
如何使用python技术爬取下载百度文库文档?
开发语言·python·百度
羚羊角uou35 分钟前
【C++】模板(进阶)
开发语言·c++
此般纯净1 小时前
Ubuntu、Windows系统网络设置(ping通内外网)
linux·开发语言
前端 贾公子1 小时前
速通Docker === 快速部署Redis主从集群
java·开发语言