WPF 笔记3——在XAML中给对象属性赋值

news2024/9/22 1:45:28

看B站刘铁猛老师视频学习WPF

XAML语言是从xml文件派生而来,是声明式语言,一个标签就表示声明了一个对象。

对象的值可以存储在对象的字段中,也可存储在对象的属性中;

通过给对象的属性赋值,可以在赋值时检查值的合法性,如果不合法可以抛异常给提示。

在XAML中给对象的属性赋值有3中方式:

  • Attribute=value
  • 属性标签
  • 标签扩展

1、Attribute=value

优点:简单快捷

缺点:不易给属性赋复杂值


        <Rectangle Height="50" Width="200" Stroke="Red" Fill="Gold" RadiusX="20" RadiusY="10"></Rectangle> 
        
        <Path Data="M 0,0 L 200,100  L 100,200 Z" Stroke="Red" Fill="Green" ></Path>

        <!--Path对象的Data属性值稍复杂-->
        <!--两个对象中都有Stroke属性,类型是Brush-->

Path对象的Data属性是Geometry类型, Data="M 0,0 L 200,100  L 100,200 Z"实现了对Data的赋值。然而这对于人来说是既不易阅读,也不易书写。

如果属性的类型比Data还复杂,就需要使用第二种方式进行赋值了。

补充:

两个对象中都有Stroke、Fill属性,类型都是Brush;

在xaml文件中,对Stroke属性赋的是字符串,这个字符串最后都被转换Stroke对象了 

这是怎么实现的呢?

(1)在后台文件中添加Person类

public class Person
    {
        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 母亲
        /// </summary>
        public Person Mother { get; set; }
        /// <summary>
        /// 父亲
        /// </summary>
        public Person Father { get; set; }
    }

(2)在前台文件中添加资源

资源是通过key来检索的,资源中添加Person对象时候,需要指定一个key

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

    <Window.Resources>
        <!--资源是通过key来检索的,在资源中添加对象时需要指定key-->
        <local:Person x:Key="pon" Name="Jeff" ></local:Person>
    </Window.Resources>
    
    <Grid>

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

    </Grid>
</Window>

(3)编辑Button_Click事件


        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //通过key检索资源
            Person p = this.FindResource("pon") as Person;
            if (p == null)
            {
                MessageBox.Show("空对象");
            }
            else
            {
                StringBuilder sb = new StringBuilder($"姓名:{p.Name}\n");
                if (p.Mother != null)
                {
                    sb .Append($"妈妈:{p.Mother.Name}\n");
                }
                if (p.Father != null)
                {
                    sb.Append($"爸爸:{p.Father.Name}\n");
                }
                MessageBox.Show(sb.ToString());
            }
        } 

运行效果:

(4)给Person的其他属性赋值

<local:Person x:Key="pon" Name="Jeff" Mother="Anna" ></local:Person>

运行效果:

(5)报异常了,显然我们不能给复杂属性(Mother、Father) 直接使用Attribute=value方式赋值,那么怎么样才能像前文中那样Stroke="Red" Fill="Gold"?

这就需要用到System.ComponentModel.TypeConverter类了

添加声明一个新类,继承自System.ComponentModel.TypeConverter


    /// <summary>
    /// 通过重新ConvertFrom方法实现将一个简单类型,通过赋值,转换成一个复杂对象 
    /// </summary>
    public class NameToPersonTypeConvert : System.ComponentModel.TypeConverter
    {
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            string name = value.ToString();
            Person person = new Person();
            person.Name = name;
            return person;
            //return base.ConvertFrom(context, culture, value);
        }
    }

(6)下一步就是把这个类附加到Person上,

    //将NameToPersonTypeConvert类以特性方式附加到Person类上
    [TypeConverterAttribute(typeof(NameToPersonTypeConvert))]
    public class Person
    {
        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 母亲
        /// </summary>
        public Person Mother { get; set; }
        /// <summary>
        /// 父亲
        /// </summary>
        public Person Father { get; set; }
    }

运行效果:

通过以上步骤,就完成了给对象的复杂类型属性赋一个简单值 


2、属性标签

在xaml中,标签是用来声明对象的。

        <!--标签内容,是夹在开始标签和结束标签之间的部分。注意区分概念-->
        <Button Width="100" Height="50" Content="这里是对象的内容">
            这里是标签的内容
        </Button>

属性标签的格式是:<类名.属性名></类名.属性名>

缺点:代码变多

示例1:

Button的Content是object类型



        <Button Width="100" Height="50" >
            <Button.Content>
                <Rectangle Width="20" Height="20" Stroke="Green" Fill="Green"></Rectangle>
            </Button.Content>
        </Button>

示例2:

Rectangle的Fill是Brush类型

        <Rectangle Width="400"  Height="400" Stroke="Blue">
            <Rectangle.Fill>
               <!--设置渐变填充-->
                <LinearGradientBrush>
                    <LinearGradientBrush.StartPoint>
                        <!--开始位置-->
                        <Point X="0" Y="0"></Point>
                    </LinearGradientBrush.StartPoint>
                    <LinearGradientBrush.EndPoint>
                        <!--结束位置-->
                        <Point X="1" Y="1"></Point>
                    </LinearGradientBrush.EndPoint>
                    <LinearGradientBrush.GradientStops>
                        <GradientStopCollection>
                            <!--设置描述渐变中转换点的位置和颜色-->
                            <GradientStop Offset="0.1" Color="Red"></GradientStop>
                            <GradientStop Offset="0.3" Color="Yellow"></GradientStop>
                            <GradientStop Offset="0.5" Color="Green"></GradientStop>
                            <GradientStop Offset="0.7" Color="Pink"></GradientStop>
                            <GradientStop Offset="0.9" Color="Pink"></GradientStop>
                        </GradientStopCollection>
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

补充:

(1)Brush的类图关系如下:

(2)注意要点

  • 能用attribute=value方式赋值是,就不要用属性标签;
  • 如果要赋的值正好是默认值,就不要用在属性标签中写出来;
  • 对于属性标签,如果属性值是一组集合,可以不写集合的名称,直接罗列集合元素

示例2的代码可优化成这种方式:


        <Rectangle Width="400"  Height="400" Stroke="Blue">
            <Rectangle.Fill>
                <!--开始点、结束点使用attri=value方式赋值 -->
                <!-- 
                    StartPoint="0,0" EndPoint="1,1" 
                   是LinearGradientBrush 的默认值,在这里可以不写
                -->
                <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> 
                    <LinearGradientBrush.GradientStops> 
                            <!--属性标签是集合,可以直接罗列元素不写属性名称-->
                            <GradientStop Offset="0.1" Color="Red"></GradientStop>
                            <GradientStop Offset="0.3" Color="Yellow"></GradientStop>
                            <GradientStop Offset="0.5" Color="Green"></GradientStop>
                            <GradientStop Offset="0.7" Color="Pink"></GradientStop>
                            <GradientStop Offset="0.9" Color="Pink"></GradientStop> 
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>
        

3、标签扩展

        标签扩展方式赋值与attribute=value赋值方式类型,只是这个value比较特殊,是花括号括起来的一组值。

        WPF中的标签扩展是有限的,我们只要掌握常用的即可
示例1

StaticResource 标签扩展

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <!--
            在资源中定义字符串,这里需要添加命名空间如下
            xmlns:sys="clr-namespace:System;assembly=mscorlib"
        -->
        <sys:String x:Key="strHello">Hello World</sys:String>
    </Window.Resources>
    <Grid>
        <!--文本框显示的字符串来自Window.Resources-->
        <TextBlock Height="30" Width="200" Background="LightYellow" Text="{StaticResource ResourceKey=strHello}"> </TextBlock>
        <TextBlock Height="30" Width="200" Background="LightPink" Text="{StaticResource strHello}" Margin="262,251,330,138"></TextBlock>
    </Grid>
</Window>

运行效果:

示例2

Binding标签扩展

    <Grid> 
        <Grid.RowDefinitions>
            <RowDefinition Height="30"></RowDefinition>
            <RowDefinition Height="3"></RowDefinition>
            <RowDefinition Height="30"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock x:Name="tb" Text="{Binding ElementName=sld,Path=Value}" Width="150" Height="25" Background="LightCoral"></TextBlock>
        <Slider x:Name="sld" Grid.Row="2" Value="50" Maximum="100" Minimum="0"  ></Slider> 
    </Grid>

运行效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/172059.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis6学习笔记【part2】基本数据类型与常用命令

一.单线程多路IO复用技术 Redis是单线程多路IO复用技术。多路复用是指使用一个线程来检查多个文件描述符&#xff08;Socket&#xff09;的就绪状态&#xff0c;比如调用 select 和 poll 函数&#xff0c;传入多个文件描述符&#xff0c;如果有一个文件描述符就绪&#xff0c;则…

【make、makefile】

前言 打怪升级第&#xff1a;26天 | make、Makefile make是一条命令&#xff0c;Makefile是一个文件&#xff0c; make是一个命令工具&#xff0c;是一个解释Makefile文件中指令的命令工具。 makefile是一个围绕依赖关系和依赖方法构造的一个自动化编程工具&#xff0c; 一个…

博客部署教程

1:安装Docker yum install -y yum-utils device-mapper-persistent-data lvm2 //安装必要工具yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo //设置yum源yum install -y docker-ce //下载dockersystemctl start docker //启…

excel函数技巧:两个查询函数的用法比较 下篇

VLOOKUP和LOOKUP这对高频函数的较量注定是场持久战。在前两个回合的较量中&#xff0c;VLOOKUP占据上风&#xff0c;此番更要乘胜追击。新一轮较量&#xff0c;即刻开战&#xff01;***ROUND 03 交叉查询什么是交叉查询&#xff1f;我们可以通过一个查找值查找多个字段。如果被…

Android 深入系统完全讲解(26)

AudioTrack 构造过程 每一个音频流对应着一个 AudioTrack 类的一个实例&#xff0c;每个 AudioTrack 会在创建时注册到 AudioFlinger 中&#xff0c;由 AudioFlinger 把所有的 AudioTrack 进行混合&#xff08;Mixer&#xff09;&#xff0c;然后输送到 AudioHardware 中进行播…

spice auth过程分析

1、客户端选择认证方法 Client authentication method selection抓包分析{Authentication selected by client: Spice (1)}代码分析spice_channel_send_link(channel);if (!spice_channel_recv_link_hdr(channel) ||!spice_channel_recv_link_msg(channel) ||!spice_channel_re…

Allegro如何设计线圈操作指导

Allegro如何设计线圈操作指导 在做PCB设计的时候,在特殊场合时候需要设计线圈,Allegro支持快速设计出线圈,如下图 具体操作如下 选择File选择Change Editor

实现树莓派homeassistant OS远程控制内网穿透--ddnsto教程

一、两种穿透服务 1、molohub 一种是论坛提供的molohub&#xff0c;但是可能因为自己这边的网络原因在配置过程中一直无法连接到服务器&#xff0c;无法绑定github&#xff0c;因此放弃molohub的方法。如下图所示。molohub教程如下&#xff0c;不再赘述。 molohub的Github教程…

ejson4cpp——一个使用极致简单且性能可比rapidjson的C++json解析库

文章目录ejson4cpp快速开始要求安装与引入开始使用常见用法API介绍通过命名风格识别API宏定义FROM_JSON_FUNC&FROM_JSON_FRIEND_FUNCTO_JSON_FUNC&TO_JSON_FRIEND_FUNCAUTO_GEN_NON_INTRUSIVE&AUTO_GEN_INTRUSIVEENABLE_JSON_COUTFromJSON系列函数参数说明使用示例…

WireShark从入门到精通

一、什么是WireShark&#xff1f;Wireshark 是一个开源抓包工具或者叫网络嗅探器&#xff0c;用于分析网络流量和分析数据包。其实WireShark以前的名字不叫WireShark&#xff0c;以前都叫做Ethereal&#xff0c;于1998 年首次开发&#xff0c;直到 2006 年才改为 Wireshark。Wi…

powerdns 系列之二 PowerDNS Authoritative Server

PowerDNS Authoritative Server 权威服务器&#xff0c;直接查询数据库去尝试解析&#xff0c;数据库中若不存在此记录&#xff0c;则直接返回空结果。 os: centos 7.8.2003 pnds: 4.7.3 安装 pdns 安装 pdns auth yum install epel-release yum-plugin-priorities curl -o…

Alibaba微服务组件Nacos注册中心学习笔记

1. 什么是 Nacos 什么是 Nacos官方网站:什么是 Nacos 官方&#xff1a;一个更易于构建云原生应用的动态服务发现(Nacos Discovery )、服务配置(Nacos Config)和服务管理平台。 集 注册中心配置中心服务管理 平台 Nacos 的关键特性包括: 服务发现和服务健康监测 动态配置服…

Vue前端项目【尚品汇】

Vue前端项目【尚品汇】1. 说明2. 对项目创建3.结构4. 项目运行起来时&#xff0c;浏览器自动打开5.关闭ESLint校验功能1. 说明 学习完了Vue后并没有一个整体的项目&#xff0c;让我明白前端的工程化开发。因此在B站找了一个开源的项目进行练手&#xff0c;并在这里进行记录。 …

深度学习理论介绍

在机器学习理论介绍中说过&#xff0c;深度学习是机器学习的一种技术&#xff0c;下面我们具体来看下。 1、 定义 深度学习首先是一种机器学习。深度学习的基础&#xff0c;叫做神经网络&#xff0c;这本身就是一种机器学习算法。 深度神经网络&#xff08;Deep Neural Netwo…

产品小白如何从模仿开始学习Axure

​有一些小伙伴有这样的疑问&#xff0c;如果想学习产品经理的知识&#xff0c;但是从来对产品经理完全没有认识&#xff0c;该怎样去开始学习呢&#xff1f; 对于这种情况的小伙伴&#xff0c;有个建议是可以先从axure的学习入手。 那么问题又来了&#xff0c;应该如何开始axu…

只靠石墨烯电池,撑不起两轮电动车的“高端梦”

文|智能相对论作者|陈明涛在两轮电动车上&#xff0c;“石墨烯”电池已经成为品牌标配。雅迪、爱玛、台铃等都有搭载石墨烯电池的车型&#xff0c;雅迪的TTFAR石墨烯电池已经迭代到第4代&#xff0c;而第3代Plus电池搭载在冠能3 E9 PRO上完成量产上市&#xff1b;爱玛、台铃都和…

(侯捷C++)1.1面向对象高级编程(上)

一.C编程简介 1.C历史 B语言 → C语言 → C语言&#xff08;new C → C with Class → C&#xff09; 面向对象的语言&#xff1a;C、Java、C# 2.C演化 C 98(1.0) → C 03 → C 11(2.0) → C 14 Class两个经典分类&#xff1a;有指针&#xff08;Complex类为例&#xff0…

python经典例题

目录标题1&#xff0c;计算数字的阶乘2&#xff0c;区间内的所有素数3&#xff0c;求前n个数字的平方和4&#xff0c;移除列表中的多个元素5&#xff0c;列表去重6&#xff0c;对简单列表元素排序7&#xff0c;对复杂列表元素排序8&#xff0c;读取成绩问卷并排序-读取文件&…

在MySQL5基础上安装MySQL8解压版安装服务指向MySQL5的问题

Windows10在MySQL5解压版基础上安装MySQL8解压版后服务启动失败 1. 遇到的问题&#xff1a; MySQL8目录下没有生成data文件夹启动服务失败&#xff0c;右键服务属性&#xff0c;可执行文件的路径竟然是MySQL目录下的日志文件在MySQL5目录下&#xff0c;日志内容会提示读取了M…

【C语言】动态内存实现通讯录(malloc,calloc,realloc)

目录 一、为什么要存在动态内存开辟 二、动态内存函数 2.1 malloc 2.1.1 函数介绍 2.1.2 函数的使用 2.1.3 free 2.2 calloc 2.2.1 函数介绍 2.2.2 函数的使用 2.3 realloc 2.3.1 函数的介绍 2.3.2 函数的使用 三、改进通讯录 3.1 初始化 3.2 增加信息 3.3 排序&am…