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

4

转换器的生命周期是什么?
当你从 IValueConverterIMultiValueConverter 派生出一个转换器时,这个类不是静态的,Convert()ConvertBack() 函数也不是静态的。那么这个类实例的生命周期是什么样的呢?
如果我在XAML中使用该转换器来绑定多个控件,那么每个控件都会创建一个新的类实例吗?还是每次绑定更新时都会创建一个新的类实例?或者可能整个应用程序只有一个实例?


这取决于您如何定义转换器。请展示您如何定义和使用它。 - mm8
2个回答

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解析器的行为会有所不同。您可以像上面那样将对象实例分配给属性作为资源。但是,您也可以使用属性元素语法来实例化XAML对象:
<Binding Path="Values">
    <Binding.Converter>
        <BooleanToVisibilityConverter />
    </Binding.Converter>
</Binding>

此声明会生成一个转换器实例,该实例仅用于此特定的绑定(或属性)。此声明不引用资源(使用StaticResourceDynamicResource),而是显式创建一个专门分配给属性的实例(在本例中为Binding.Converter)。
顺便提一下:
StaticResource并不意味着资源是静态的。它是一种标记扩展,指示XAML解析器查找资源树以查找预定义的实例。 DynamicResource也是如此。唯一的区别是StaticResource指示XAML解析器在编译时解析对资源的引用,而DynamicResource则让XAML解析器创建一个表达式,该表达式将在运行时评估。因此,DynamicResource在运行时解析资源。

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

以下是结果图片: 输入图像描述

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接