1、attribute的形式和对象属性赋值

attribute的形式是最为简单的,就是直接在属性上赋值,如下红色背景部分:

<Window x:Class="MyWpf.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:MyWpf"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <local:Human x:Key="human" Name="tom" Child="any"></local:Human>
    </Window.Resources>
    <Grid></Grid>
</Window>

 这是最简单的,如果要将对象进行属性赋值,就需要用TypeConverter,比如上述代码中有Human类如下,对数据进行转换:

//使用HumanTypeConvert转换器
    [TypeConverter(typeof(HumanTypeConvert))]
    public class Human
    {
        public string Name { get; set; }
        public Human Child { get; set; }
    }
    /// <summary>
    /// 类型转换器
    /// </summary>
    public class HumanTypeConvert : TypeConverter
    {
        public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
        {
            Human human = new Human();
            human.Name = value.ToString();
            return human;
        }
    }

然后就可以从xamlresource中获取human对象了:

//xaml中resource的key
  var model = this.FindResource("human") as Human;
  if(model != null)
  {
    var str = model.Name;
    if(model.Child != null)
    {
      str += model.Child.Name;
    }
    MessageBox.Show(str);
  }

 2、属性标签

像是一般的属性比如Text=“xxx”这种赋值是简单的,但是如果是以一个复杂的对象,比如对象的列表就做不到了。如下所示的RectangleFill属性,对象很复杂可以用xx.xx的形式进行赋值。

<Rectangle Width="50" Height="50" Stroke="Green">
  <!--属性可以用xx.xx的形式-->
  <Rectangle.Fill>
    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
      <LinearGradientBrush.GradientStops>
        <GradientStop Offset="0.2" Color="LightBlue" />
        <GradientStop Offset="0.7" Color="DarkBlue" />
        <GradientStop Offset="1.0" Color="Blue" />
      </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
  </Rectangle.Fill>
</Rectangle>

 3、属性标签的扩展

我们可以通过资源加载的方式来给属性赋值,如下所示我们在button组件下定以了一个名叫MyLinearGradientBrush的资源,然后我们通过DynamicResource动态加载资源。

 <Button Click="Button_Click" Width="200" Height="50" Name="button">
  <Button.Resources>
    <!--每个控件下也可以有资源,资源名称重复时取里的最近的资源类似html的css-->
    <LinearGradientBrush x:Key="MyLinearGradientBrush" StartPoint="0,0" EndPoint="1,1" >
      <GradientStop Offset="0.2" Color="LightBlue" />
      <GradientStop Offset="0.7" Color="DarkBlue" />
      <GradientStop Offset="1.0" Color="Blue" />
    </LinearGradientBrush>
  </Button.Resources>
  <!--属性标签可以更复杂属性赋值,但是会使代码变得复杂-->
  <Button.Content>
    <Rectangle Width="50" Height="50" Stroke="Green" Fill="{DynamicResource ResourceKey=MyLinearGradientBrush}">
    </Rectangle>
  </Button.Content>
</Button>

 如果想要修改这个资源,则在后端代码如下:

//修改DynamicResource动态数据源            
  //var linearGradientBrush = this.Resources["MyLinearGradientBrush"] as LinearGradientBrush
  var linearGradientBrush = new LinearGradientBrush();
  linearGradientBrush.StartPoint = new System.Windows.Point(0, 0);
  linearGradientBrush.EndPoint = new System.Windows.Point(1, 1);
  linearGradientBrush.GradientStops.Add(new GradientStop(System.Windows.Media.Color.FromRgb(97,168,13), 0.5));
  linearGradientBrush.GradientStops.Add(new GradientStop(System.Windows.Media.Color.FromRgb(1, 2, 3), 1));
  //这里只能取到window下的资源
  //this.Resources["MyLinearGradientBrush"] = linearGradientBrush;
  //获取控件下的资源
  this.button.Resources["MyLinearGradientBrush"] = linearGradientBrush;

上面使用动态加载资源因为可以修改,使用StaticResource也可以加载资源但是一次加载不能修改,如下所示:

    <Window.Resources>
        <sys:String x:Key="stringHello">Hello WPF!</sys:String>
    </Window.Resources>
    <Grid>
        <!--标签扩展,这里使用静态资源-->
        <TextBlock Height="24" Width="120" Background="LightBlue" Text="{StaticResource ResourceKey=stringHello}" Margin="20,0,0,0" HorizontalAlignment="Left" />
    </Grid>