转换器的生命周期是什么?

时间:2019-07-09 23:46:26

标签: wpf xaml lifecycle converters

转换器的生命周期是什么?
当您制作从IValueConverterIMultiValueConverter派生的转换器时,该类不是静态的,Convert()ConvertBack()函数也不是。那么该类实例的生命周期是什么?
如果我在多个绑定中的XAML中使用了转换器,是否为每个控件都创建了该类的新实例?还是在每次更新绑定时创建该类的新实例?也许整个应用程序只有一个实例?

2 个答案:

答案 0 :(得分:2)

转换器的生命周期通常与任何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并不意味着资源是静态的。这是一个标记扩展,它指示XAML解析器查找资源树以查找预定义的实例。 DynamicResource也是如此。唯一的区别是StaticResource指示XAML解析器在编译时解析对资源的引用,而DynamicResource让XAML解析器创建一个表达式,该表达式将在运行时进行评估。 DynamicResource因此会在运行时解析资源。

答案 1 :(得分:0)

转换器的实例号取决于您的代码。您可以自己尝试以下代码:

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;
        }
    }
}

结果图片如下: enter image description here