转换器的生命周期是多少?

What is the lifecycle of a converter?

转换器的生命周期是多少?
当您创建从 IValueConverterIMultiValueConverter 派生的转换器时,class 不是静态的,Convert()ConvertBack() 函数也不是。那么 class 实例的生命周期是多少?
如果我在多个 Binding 中使用 XAML 中的转换器,是否为每个控件创建了 class 的新实例?还是每次更新 Binding 时都会创建 class 的新实例?或者整个应用程序可能只有一个实例?

converter的实例数取决于你的code.You可以自己试试这个代码:

Xaml

<Window x:Class="ConverterTest.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:ConverterTest"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.Resources>
    <local:ToStringConverter x:Key="StaticToStringConverter"/>
</Window.Resources>
<StackPanel>
    <Slider x:Name="Slider"/>
    <TextBlock Text="{Binding ElementName=Slider,Path=Value,Converter={local:ToStringConverter}}"/>
    <TextBlock Text="{Binding ElementName=Slider,Path=Value,Converter={local:ToStringConverter}}"/>
    <TextBlock Text="{Binding ElementName=Slider,Path=Value,Converter={StaticResource StaticToStringConverter}}"/>
    <TextBlock Text="{Binding ElementName=Slider,Path=Value,Converter={StaticResource StaticToStringConverter}}"/>
</StackPanel>

xaml.cs

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;

namespace ConverterTest
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    sealed class ToStringConverter : MarkupExtension, IValueConverter
    {
        Guid guid = Guid.NewGuid();


        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Console.WriteLine(guid);
            return $"{guid.ToString()}:{value.ToString()}";
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        private ToStringConverter _converter;
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (_converter == null)
            {
                _converter = new ToStringConverter();
            }
            return _converter;
        }
    }
}

结果图如下:

转换器的生命周期通常与任何 XAML 对象实例相同,并且取决于声明。通常转换器被声明为 ResourceDictionary:

的资源
<Window.Resources>
    <BooleanToVisibilityConverterx:Key="BooleanToVisibilityConverter" />
</Window.Resources>

在这种情况下,转换器(或一般的资源)被重复用于对它的每个引用。这是因为 x:Shared 属性。该属性默认为 true,它指示 XAML 解析器重用对象的实例。您可以将其明确设置为 false:

<Window.Resources>
    <BooleanToVisibilityConverterx:Key="BooleanToVisibilityConverter" x:Shared="False" />
</Window.Resources>

现在每次引用资源时,XAML 解析器都会创建一个新实例。

如果在 ResourceDictionary 之外声明对象,XAML 解析器的行为是不同的。您可以像上面那样将对象实例作为资源分配给 属性。但是您也可以使用 Property Element Syntax 来实例化一个 XAML 对象:

<Binding Path="Values">
    <Binding.Converter>
        <BooleanToVisibilityConverter />
    </Binding.Converter>
</Binding>

此声明生成转换器实例,仅用于此特定绑定(或 属性)。此声明不引用资源(使用 StaticResource or DynamicResource)但显式创建一个专门分配给 属性 的实例(在本例中为 Binding.Converter)。

旁注:
StaticResource does not mean that the resource is static. It's a markup extension that instructs the XAML parser to lookup the resource tree to find a predefined instance. Same does DynamicResource。唯一的区别是 StaticResource 指示 XAML 解析器在编译时解析对资源的引用,而 DynamicResource 让 XAML 解析器创建一个表达式,它将在 运行 时间进行评估。 DynamicResource 因此在 运行 时解析资源。