转换器的生命周期是什么?
当你从 IValueConverter
和 IMultiValueConverter
派生出一个转换器时,这个类不是静态的,Convert()
和 ConvertBack()
函数也不是静态的。那么这个类实例的生命周期是什么样的呢?
如果我在XAML中使用该转换器来绑定多个控件,那么每个控件都会创建一个新的类实例吗?还是每次绑定更新时都会创建一个新的类实例?或者可能整个应用程序只有一个实例?
转换器的生命周期是什么?
当你从 IValueConverter
和 IMultiValueConverter
派生出一个转换器时,这个类不是静态的,Convert()
和 ConvertBack()
函数也不是静态的。那么这个类实例的生命周期是什么样的呢?
如果我在XAML中使用该转换器来绑定多个控件,那么每个控件都会创建一个新的类实例吗?还是每次绑定更新时都会创建一个新的类实例?或者可能整个应用程序只有一个实例?
转换器的生命周期一般与任何XAML对象实例相同,取决于声明方式。通常,转换器被声明为ResourceDictionary
的资源:
最初的回答
<Window.Resources>
<BooleanToVisibilityConverterx:Key="BooleanToVisibilityConverter" />
</Window.Resources>
x:Shared
属性。此属性默认为true
,指示XAML解析器重用对象实例。您可以将其显式设置为false
: "最初的回答"<Window.Resources>
<BooleanToVisibilityConverterx:Key="BooleanToVisibilityConverter" x:Shared="False" />
</Window.Resources>
ResourceDictionary
之外,则XAML解析器的行为会有所不同。您可以像上面那样将对象实例分配给属性作为资源。但是,您也可以使用属性元素语法来实例化XAML对象:<Binding Path="Values">
<Binding.Converter>
<BooleanToVisibilityConverter />
</Binding.Converter>
</Binding>
StaticResource
或DynamicResource
),而是显式创建一个专门分配给属性的实例(在本例中为Binding.Converter
)。StaticResource
并不意味着资源是静态的。它是一种标记扩展,指示XAML解析器查找资源树以查找预定义的实例。 DynamicResource
也是如此。唯一的区别是StaticResource
指示XAML解析器在编译时解析对资源的引用,而DynamicResource
则让XAML解析器创建一个表达式,该表达式将在运行时评估。因此,DynamicResource
在运行时解析资源。转换器的实例编号取决于您的代码。 您可以自行尝试此代码:
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;
}
}
}