当前位置: 首页 > article >正文

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

  • 1. Attribute=Value方式
    • 1.1. 简单属性赋值
    • 1.2. 对象属性赋值
  • 2. 属性标签的方式给属性赋值
  • 3. 标签扩展 (Markup Extensions)
    • 3.1. StaticResource
    • 3.2. Binding
      • 3.2.1. 普通 Binding
      • 3.2.2. ElementName Binding
      • 3.2.3. RelativeSource Binding
      • 3.2.4. StaticResource Binding (带参数的 Binding)
      • 3.2.5. TemplateBinding
    • 3.3. 标签扩展总结:
    • 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 通过键名查找静态资源。这是一种在应用启动时就加载并且在整个应用程序生命周期内不会改变的资源引用方式。


<Button Content="{StaticResource MyButtonStyle}" />

3.2. Binding

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

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

3.2.1. 普通 Binding

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


<TextBlock Text="{Binding Path=Name}" />

3.2.2. ElementName Binding

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


<TextBlock Text="{Binding Path=Text, ElementName=myTextBox}" />

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

3.2.3. RelativeSource Binding

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


<TextBlock Text="{Binding Path=Name, RelativeSource={RelativeSource AncestorType=Window}}" />

3.2.4. StaticResource Binding (带参数的 Binding)

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


<TextBlock Text="{Binding Source={StaticResource MyResourceKey}}" />

3.2.5. TemplateBinding

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


<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….}"是等价的。


http://www.kler.cn/a/513474.html

相关文章:

  • C/C++、网络协议、网络安全类文章汇总
  • 2025寒假备战蓝桥杯01---朴素二分查找的学习
  • VS Code AI开发之Copilot配置和使用详解
  • ElasticSearch索引别名的应用
  • 一文大白话讲清楚webpack基本使用——2——css相关loader的配置和使用
  • 2024年第十五届蓝桥杯青少组国赛(c++)真题—快速分解质因数
  • DOL-288 多功能电子计时器说明书
  • (10)深入浅出智能合约OpenZeppelin开源框架
  • Linux内核编程(二十一)USB驱动开发-键盘驱动
  • es 3期 第25节-运用Rollup减少数据存储
  • VINS-Mono源码阅读(一)程序简介、编译调试、配置文件
  • Unity自学之旅04
  • 缓存系统(redis)测试体系
  • 智慧脚下生根,智能井盖监测终端引领城市安全新革命
  • Mybatis 进阶 / Mybatis—Puls (详细)
  • 升级《在线写python》小程序的分享功能。昨天忘了...
  • Keil5 IDE使用笔记
  • C#调用c++dll的两种方法(静态方法和动态方法)
  • 大华相机DH-IPC-HFW3237M支持的ONVIF协议
  • Apache SeaTunnel 2.3.9 正式发布:多项新特性与优化全面提升数据集成能力
  • 【Python项目】小区监控图像拼接系统
  • Spring 6 第5章——面向切面:AOP
  • Spring Boot框架下的上海特产销售商城网站开发之旅
  • Java复习第四天
  • 如何写出优秀的提示词?ChatGPT官方的六种方法
  • 【科研建模】Pycaret自动机器学习框架使用流程及多分类项目实战案例详解