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