[英]Using an IValueConverter on non bound data in XAML
I have an IValueConverter
that I wrote to handle localization and translation in WPF elements; 我编写了一个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();
}
}
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? 我该怎么办?
Guess I should clarify, my intent is to use this in XAML for the UI and would be helpful if it had a design time support aswell. 猜猜我应该澄清一下,我的意图是在XAML中将其用于UI,如果它还具有设计时间支持,将很有帮助。
I did attempt a variation that used the ConverterParameter
to feed the source string, but in design time all my text is replaced with System.Object text, so not very useful. 我确实尝试过使用ConverterParameter
来输入源字符串的变体,但是在设计时,我的所有文本都被System.Object文本替换了,所以不是很有用。
Would also like if at all possible to avoid creating a overloaded or inherited user-control. 还要尽可能避免创建重载或继承的用户控件。
You could create a MarkupExtension
that would take a string
as a parameter and call your converter in the ProvideValue
override. 您可以创建将string
作为参数的MarkupExtension
,然后在ProvideValue
覆盖中调用您的转换器。 Here's an example implementation: 这是一个示例实现:
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);
}
}
Then you'd use it in XAML like this: 然后,您将在XAML中像这样使用它:
<TextBlock Text="{local:Translate 'text to translate'}" />
Note though that changing language will require the XAML to be re-read as the ProvideValue
method is only called once upon realization of your XAML definition. 请注意,尽管更改语言将要求重新读取XAML,因为仅在实现XAML定义ProvideValue
方法。 If you want a dynamic approach you could refer for example to this answer. 如果您希望采用动态方法,则可以参考此答案。
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? 我该怎么办?
You can't really do this because the Convert method of a Converter will only be invoked when the binding to the source property is resolved and when the source property is updated. 您实际上无法做到这一点,因为仅在解析到source属性的绑定以及更新source属性时才调用Converter的Convert方法。 If the binding to the source property fails, for example when you have defined an invalid binding path in your XAML markup or when there simply is no DataContext to bind to, your Convert method won't be called. 如果与source属性的绑定失败,例如,当您在XAML标记中定义了无效的绑定路径时,或者根本没有要绑定的DataContext时,将不会调用Convert方法。
And when there is no binding applied to the target property at all, the converter won't be invoked either. 而且,如果根本没有将绑定应用于目标属性,则转换器也不会被调用。
So you will have to always make sure that there actually is a property to bind to for this to work. 因此,您必须始终确保确实存在要绑定的属性才能起作用。 Maybe you can bind to a dummy property or something. 也许您可以绑定到虚拟属性或其他东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.