WPF基础一:XAML中为对象是属性赋值的语法

XMAL中为对象是属性赋值的语法:

  • 使用标签的Attribute为对象属性赋值
  • 使用TypeConverter类将XAML标签的Attribute与对象的Property进行映射
  • 属性元素
  • 标记扩展(Markup Extensions)

一)理解Attribute与Property

Attribute:即特性,是编程语言文法层面的东西。只与语言层面上的东西相关,与抽象出来的对象没什么关系。Attribute只是用来影响类在程序中的用法。

Property:即属性,属于面向对象理论范畴。属性是针对对象而言的。

标签式语言只是把标签与对象做了一个映射,同时把标签的Attribute与对象的Property也做了一个映射。针对标签的叫Attribute。针对对象的叫Property。


二)使用标签的Attribute为对象属性赋值

语法:Attribute=Value

注意,此处Value是字符串值。

代码段1

    <!--范例--> 
    <!--Attribute=Value 的形式进行赋值的-->        

<Window x:Class="XMAL中为对象是属性赋值.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:XMAL中为对象是属性赋值"
        mc:Ignorable="d"
        Title="MainWindow" Height="150" Width="280" >
    <Grid>
        <StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="姓名:" HorizontalAlignment="Center" Width="40" Margin="20,0,0,0"/>
                <TextBlock x:Name="tbk1" HorizontalAlignment="Center" Width="180" Margin="5" TextAlignment="Center" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="班级:"  HorizontalAlignment="Center" Width="40" Margin="20,0,0,0"/>
                <TextBlock x:Name="tbk2" HorizontalAlignment="Center" Width="180" Margin="5" TextAlignment="Center" />
            </StackPanel>
            <StackPanel >
                <Button Content="显示" Width="200" Margin="0,20,0,0" Click="Button_Click"/>
            </StackPanel>
        </StackPanel>       
    </Grid>
</Window>

上面代码中的  Content="姓名:" HorizontalAlignment="Center" Width="120" 等都是以 Attribute=Value 的形式进行赋值的。

运行以上代码:


三) 使用TypeConverter类将XAML标签的Attribute与对象的Property进行映射

如果一个类能使用XAML语言进行声明并进行赋值,有时候可能需要为这些Property准备适当Converter。

如下范例:

有一个Student类和Class类

代码段2

    //学生
    public class Student
    {
        public string MyName { get; set; }
        public Class MyClass { get; set; }

    }

    //班级
    public class Class
    {
        public int ClassNo { get; set; }
        public int ClassMember { get; set; } 
        
    }

修改代码段1,添加一个名为stu的Student类,作为Window.Resources。

代码段1.1

<Window x:Class="XMAL中为对象是属性赋值.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:XMAL中为对象是属性赋值"
        mc:Ignorable="d"
        Title="MainWindow" Height="150" Width="280" >
    <Window.Resources>
        <local:Student x:Key="stu"  MyName="徐猫" MyClass="206"/>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="姓名:" HorizontalAlignment="Center" Width="40" Margin="20,0,0,0"/>
                <TextBlock x:Name="tbk1" HorizontalAlignment="Center" Width="180" Margin="5" TextAlignment="Center" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="班级:"  HorizontalAlignment="Center" Width="40" Margin="20,0,0,0"/>
                <TextBlock x:Name="tbk2" HorizontalAlignment="Center" Width="180" Margin="5" TextAlignment="Center" />
            </StackPanel>
            <StackPanel >
                <Button Content="显示" Width="200" Margin="0,20,0,0" Click="Button_Click"/>
            </StackPanel>
        </StackPanel>       
    </Grid>
</Window>

添加ButtonClick事件,用于显示UI

代码段3

    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Student s = (Student)this.FindResource("stu");
            tbk1.Text = s.MyName;
            tbk2.Text = s.MyClass.ClassNo.ToString();
        }
    }

运行后发生异常:

System.Windows.Markup.XamlParseException:““设置属性“XMAL中为对象是属性赋值.Student.MyClass”时引发了异常。

这是因为<local:Student x:Key="stu"  MyName="徐猫" MyClass="206"/>中MyClass的Value值是字符串类型,而代码段2中Student的Myclass是一个Class类型的。

两者类型不统一,需要一个转换器——Converter。

修改代码段2

代码段2.2

    //学生
    public class Student
    {
        public string MyName { get; set; }
        public Class MyClass { get; set; }

    }

    //班级
    [TypeConverter(typeof(ClassConvert))]
    public class Class
    {
        public int ClassNo { get; set; }
        public int ClassMember { get; set; } 
        
    }


    //转换器
    public class ClassConvert : TypeConverter
    {
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string)
            {
                Class _class = new Class();
                _class.ClassNo = Convert.ToInt32(value);
                return _class;
            }
            return base.ConvertFrom(context, culture, value);
        }
    }

此时,运行后并点击按钮后的结果如下图:


四) 属性元素

属性元素:某个标签的一个元素对应这个标签的一个属性。

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

范例:

<Border BorderBrush="Red" CornerRadius="10"  Height="50" Margin="0 5 0 0" BorderThickness="2" >
    <Border.Background>
        <SolidColorBrush Color="DarkOliveGreen" Opacity="0.5"/>
    </Border.Background>
</Border>

 


   
五) 标记扩展(Markup Extensions)

是一种特殊的Attribute=Value语法,Value字符串是由一对花括号和被括内容组成。

            <StackPanel Orientation="Horizontal">
                <Label Content="班级:"  HorizontalAlignment="Center" Width="40" Margin="20,0,0,0"/>
                <TextBlock x:Name="tbk2" HorizontalAlignment="Center" Width="180" Margin="5" TextAlignment="Center"  Text="{Binding Source={StaticResource stu}, Path=MyClass.ClassNo}"/>
            </StackPanel>

 Text="{Binding Source={StaticResource stu}, Path=MyClass.ClassNo}"就是一个扩展标签。

只有MarkupExtension的派生类才能使用标记扩展的语法来写。

System.Activities.Presentation.CachedResourceDictionaryExtension

System.Activities.XamlIntegration.DynamicUpdateMapExtension

System.Activities.XamlIntegration.PropertyReferenceExtension<T>

System.ServiceModel.EndpointIdentityExtension

System.ServiceModel.XamlIntegration.SpnEndpointIdentityExtension

System.ServiceModel.XamlIntegration.UpnEndpointIdentityExtension

System.ServiceModel.XamlIntegration.XPathMessageContextMarkupExtension

System.Windows.ColorConvertedBitmapExtension

System.Windows.Data.BindingBase

System.Windows.Data.RelativeSource

System.Windows.DynamicResourceExtension

System.Windows.Markup.ArrayExtension

System.Windows.Markup.NullExtension

System.Windows.Markup.Reference

System.Windows.Markup.StaticExtension

System.Windows.Markup.TypeExtension

System.Windows.ResourceKey

System.Windows.StaticResourceExtension

System.Windows.TemplateBindingExtension

System.Windows.ThemeDictionaryExtension

  • 标记扩展是可以嵌套的。
  • 标记扩展具有一些简写方法。“{Binding Value}”与“{Binding Path=Value}”等价
  • 标记扩展类的类名均以Extension结尾,在XAML中可以省略不写。

 

简化XAML技巧:

  • 能使用Attribute=Value形式赋值的就不使用属性元素
  • 充分利用默认属性,默认属性可以省略不写。
  • 充分利用XAML的简写方法。

 

参开文献:《深入浅出WPF》刘铁锰

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值