在 XAML 中对非绑定数据使用 IValueConverter
Using an IValueConverter on non bound data in XAML
我写了一个 IValueConverter
来处理 WPF 元素中的本地化和翻译;
public class LanguageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return string.Empty;
if (value is string)
return LocalizedStrings.Retreive((string)value);
else
return string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
但我也想在非绑定数据中使用它,即将已知字符串发送到转换器而不是来自元素数据上下文的 属性。我该怎么做?
我想我应该澄清一下,我的目的是在 XAML 中为 UI 使用它,如果它也有设计时支持会很有帮助。
我确实尝试过使用 ConverterParameter
来提供源字符串的变体,但在设计时我的所有文本都被替换为 System.Object 文本,所以不是很有用。
还希望尽可能避免创建重载或继承的用户控件。
But I also want to use it in non bound data aswell, ie send a known string into the converter rather than a property from the elements data context. How can I go about that?
您实际上不能这样做,因为仅当解析到源 属性 的绑定以及更新源 属性 时,才会调用 Converter 的 Convert 方法。如果绑定到源 属性 失败,例如,当您在 XAML 标记中定义了无效的绑定路径,或者根本没有要绑定的 DataContext 时,您的 Convert 方法将不会被调用.
并且当根本没有应用到目标的绑定时 属性,转换器也不会被调用。
所以你必须始终确保确实有一个 属性 可以绑定到它才能工作。也许你可以绑定到虚拟 属性 或其他东西。
您可以创建一个 MarkupExtension
将 string
作为参数并在 ProvideValue
覆盖中调用您的转换器。这是一个示例实现:
public class TranslateExtension : MarkupExtension
{
public TranslateExtension(string text)
{
Text = text;
}
private static readonly LanguageConverter _converter = new LanguageConverter();
public string Text { get; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return _converter.Convert(Text, null, null, null);
}
}
然后您可以像这样在 XAML 中使用它:
<TextBlock Text="{local:Translate 'text to translate'}" />
请注意,更改语言需要 XAML 变为 re-read,因为 ProvideValue
方法仅在实现您的 XAML 定义时调用一次。如果你想要一个动态的方法,你可以参考 答案。
我写了一个 IValueConverter
来处理 WPF 元素中的本地化和翻译;
public class LanguageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return string.Empty;
if (value is string)
return LocalizedStrings.Retreive((string)value);
else
return string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
但我也想在非绑定数据中使用它,即将已知字符串发送到转换器而不是来自元素数据上下文的 属性。我该怎么做?
我想我应该澄清一下,我的目的是在 XAML 中为 UI 使用它,如果它也有设计时支持会很有帮助。
我确实尝试过使用 ConverterParameter
来提供源字符串的变体,但在设计时我的所有文本都被替换为 System.Object 文本,所以不是很有用。
还希望尽可能避免创建重载或继承的用户控件。
But I also want to use it in non bound data aswell, ie send a known string into the converter rather than a property from the elements data context. How can I go about that?
您实际上不能这样做,因为仅当解析到源 属性 的绑定以及更新源 属性 时,才会调用 Converter 的 Convert 方法。如果绑定到源 属性 失败,例如,当您在 XAML 标记中定义了无效的绑定路径,或者根本没有要绑定的 DataContext 时,您的 Convert 方法将不会被调用.
并且当根本没有应用到目标的绑定时 属性,转换器也不会被调用。
所以你必须始终确保确实有一个 属性 可以绑定到它才能工作。也许你可以绑定到虚拟 属性 或其他东西。
您可以创建一个 MarkupExtension
将 string
作为参数并在 ProvideValue
覆盖中调用您的转换器。这是一个示例实现:
public class TranslateExtension : MarkupExtension
{
public TranslateExtension(string text)
{
Text = text;
}
private static readonly LanguageConverter _converter = new LanguageConverter();
public string Text { get; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return _converter.Convert(Text, null, null, null);
}
}
然后您可以像这样在 XAML 中使用它:
<TextBlock Text="{local:Translate 'text to translate'}" />
请注意,更改语言需要 XAML 变为 re-read,因为 ProvideValue
方法仅在实现您的 XAML 定义时调用一次。如果你想要一个动态的方法,你可以参考