WPF筆記7——TypeConverter型別

青云Zeo發表於2024-12-02

自定義物件如下:

點選檢視程式碼
    public class Human
    {
        public string Name { get; set; }

        public Human Child { get; set; }
    }

需求1:點選介面上Button時彈出Human物件的Name資訊

程式碼實現:

點選檢視程式碼
<Window x:Class="HappyWPF.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:HappyWPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.Resources>
        <!--Button被點選後要顯示的物件Human-->
        <local:Human x:Key="human" Name="Tim"/>
    </Window.Resources>
    
    <Grid> 
        <Button  Content="Show" Width="200" Height="50" Click="Button_Click"/>
    </Grid>
</Window>

Button事件程式碼:

點選檢視程式碼
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Human h = this.FindResource("human") as Human;
            if (h != null)
            {
                MessageBox.Show(h.Child.Name);
            }
        }

需求2:點選介面上Button時彈出Human物件的Child的Name資訊
前臺程式碼修改如下:

點選檢視程式碼
<Window x:Class="HappyWPF.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:HappyWPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.Resources>
        <!--給物件Human的Child賦值-->
        <local:Human x:Key="human" Name="Tim" Child="LittleTim"/>
    </Window.Resources>
    
    <Grid>
        
        <Button  Content="Show" Width="200" Height="50" Click="Button_Click"/>
    </Grid>
</Window>

直接執行會報錯,原因是在xaml檔案中Child="LittleTim"我們將string型別賦值給Child了,

但Child是Human型別,現在的程式碼無法將string轉換成Human型別 。

對於這個問題,WPF給我們提供了一個TypeConverter型別。

TypeConverter位於System.ComponentModel名稱空間中。

TypeConverter允許我們定義如何從字串轉換到特定的型別,以及如何將特定型別轉換會String。 

1‌、從string轉換到型別‌:當XAML解析器遇到需要設定為非字串型別的屬性時,它會使用TypeConverter將字串值轉換為所需的型別。

‌2、從型別轉換到string:在某些情況下,可能需要將型別的值轉換為字串表示,例如在屬性編輯器中顯示值。



使用TypeConverter通常需要執行以下步驟:

1、建立自定義的TypeConverter:

* 繼承自 TypeConverter 類。

* 重寫 CanConvertFrom 方法來指定可以從哪些型別轉換。

* 重寫 CanConvertTo 方法來指定可以轉換到哪些型別。

* 重寫 ConvertFrom 方法來實現從其他型別到目標型別的轉換。

* 重寫 ConvertTo 方法來實現從目標型別到其他型別的轉換。

2、應用TypeConverter:

* 在xaml中,使用 x:TypeArguments屬性指定要轉換的型別(如果TypeConverter是泛型的)。

* 在程式碼中,可以直接使用TypeConverter類進行轉換。

3、在xaml中使用TypeConverterAttribute(可選):

* 如果我們希望在xaml中自動使用自己TypeConverter,可以在目標型別或屬性上應用TypeConverterAttribute。

現在我們繼續修改程式碼來實現需求2

繼承TypeConverter類來定義我們自己的轉換類:

點選檢視程式碼
    public class NameToHumanTypeConverter : TypeConverter
    {
        public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
        {
            if (value is string name)
            {
                Human child = new Human()
                {
                    Name = name
                };
                return child;
            }
            return base.ConvertFrom(context, culture, value);
        }
    }

給Human型別新增上標籤,轉換使用的是NameToHumanTypeConverter型別的轉換器

點選檢視程式碼
    // 在Human上應用TypeConverterAttribute以指定轉換器
    [TypeConverterAttribute(typeof(NameToHumanTypeConverter))]
    public class Human
    {
        public string Name { get; set; }

        public Human Child { get; set; }
    }
現在執行程式就可以實現需求效果了。

相關文章