今天开始翻看了刘铁猛老师的《深入浅出WPF》课程的视频录播来重温WPF技术,看到刘铁猛老师为对象赋值时使用到了类型转换(TypeConverter)公共类时有很多弹幕就说已经看不懂了,我又想到我刚开始了解时也是不明白到底什么意思所以在此写下笔记作为学习经历。
先说下实现功能,功能是通过UI显示的按钮,点击事件后将 string类型名称赋值给 human(自定义类)类型,并显示到前端。
其中NameToHumanTypeConverter类继承了TypeConverter类,human类增加了[TypeConverterAttribute(typeof(NameToHumanTypeConverter))]特性,看弹幕很多同学是不明白这里为什么要加特性,首先先明白什么是特性。特性在这里的用处是让编译器知道当无法通过正常的方式初始化 Human时,可以找NameToHumanTypeConverter寻求帮助。
特性介绍:
https://learn.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/attributes/
TypeConverter的类库文档:
TypeConverter 类 (System.ComponentModel) | Microsoft Docs
前端代码
<Window x:Class="WpfPractise.Practise31.Practise31"
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:WpfPractise.Practise31"
mc:Ignorable="d"
Title="Practise31" Height="450" Width="800">
<Window.Resources>
<local:Human x:Key="human" Name="Time" Child="LittleTime"/>
</Window.Resources>
<Grid>
<!--<Rectangle Width="100" Height="80" Stroke="Red" Fill="Blue" RadiusX="10" RadiusY="10"/>-->
<!--<Path Data="M 0,0 L 200,100 L100,200 Z" Stroke="Black" Fill="Red"/>-->
<Button Content="Show!" Width="200" Height="50" Click="Button_Click"/>
</Grid>
</Window>
后端
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace WpfPractise.Practise31
{
/// <summary>
/// 通过UI显示的按钮,点击事件后将 string类型名称赋值给 human(自定义类)类型,并显示到前端
/// </summary>
public partial class Practise31 : Window
{
public Practise31()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Human? h=this.FindResource("human") as Human;
if (h != null)
{
MessageBox.Show(h.Child.Name);
}
}
}
[TypeConverterAttribute(typeof(NameToHumanTypeConverter))]
public class Human
{
public string Name { get; set; }
public Human Child { get; set; }
}
public class NameToHumanTypeConverter:TypeConverter
{
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
string name = value.ToString();
Human child = new Human();
child.Name = name;
return child;
//return base.ConvertFrom(context, culture, value);
}
}
}