目前,我使用值转换器为 GUI 生成用户友好的字符串。例如,我有一个窗口,在状态栏中显示可用实体的数量。Viewmodel 仅具有调用代码可以设置的 int 依赖属性,然后在显示实体数量的文本框的绑定上,我指定了 int 依赖属性和将“x”更改为“x 可用实体”的值转换器”。
我的代码开始充斥着这些转换器,并且我的 XAML 中有大量烦人的资源声明,但我喜欢它们,因为所有特定于 GUI 的字符串格式都在转换器中被隔离并且调用代码没有不必担心。但是,我想知道这是否不是价值转换器的目的。
目前,我使用值转换器为 GUI 生成用户友好的字符串。例如,我有一个窗口,在状态栏中显示可用实体的数量。Viewmodel 仅具有调用代码可以设置的 int 依赖属性,然后在显示实体数量的文本框的绑定上,我指定了 int 依赖属性和将“x”更改为“x 可用实体”的值转换器”。
我的代码开始充斥着这些转换器,并且我的 XAML 中有大量烦人的资源声明,但我喜欢它们,因为所有特定于 GUI 的字符串格式都在转换器中被隔离并且调用代码没有不必担心。但是,我想知道这是否不是价值转换器的目的。
如果您将 valueconverter 用于其设计用途,那并不是“错误的”。就我个人而言,我使用它们将枚举值转换为友好的字符串,但 VC 不是将字符串硬编码到值转换器中,而是使用枚举值从资源文件中获取字符串。
在你提到的具体情况下,我会做一些不同的事情来减少你拥有的 VC 的数量——你可以只用一个来做到这一点。您正在做的是将值直接替换/插入到已知字符串中。您可以做的是开始使用ConverterParameter
您可用的,并使用它来传递资源文件中字符串的 ID,然后可以将传递给 VC 的值插入到 VCs 指定的字符串中ConverterParameter
。这是一个快速的伪代码示例:
public class MyConverter : IValueConverter
{
public MyConverter()
{
_rm = new ResourceManager("[my_assembly_name].Resources.strings", Assembly.GetExecutingAssembly());
}
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (parameter is string && !string.IsNullOrEmpty((string)parameter))
{
string z = _rm.GetString((string)parameter);
if (z != null)
{
return string.Format(z, value);
}
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
ResourceManager _rm;
}
你会像这样使用这个转换器:
<TextBlock Text={Binding someNumericValue, Converter={StaticResource MyConverter}, ConverterParameter=[key_to_resource_string]} />
另请查看 WPF4 - IIRC,它能够将格式字符串指定为绑定表达式的一部分,这也可能对您有所帮助。
我一般在视图模型中做这种转换。所以视图模型将有一个字符串依赖属性,它“装饰”了底层的 int 值。
从您的问题中不清楚 int 值如何在您的场景中更新,因此这可能是选择正确解决方案的一个因素。
恕我直言,使用视图模型更具表现力——您直接绑定到正在显示的内容,并且您的显示逻辑(我认为它)没有隐藏在转换器中,您只能通过查看XAML。
正如@slugster 提到的,该StringFormat
属性可以在Binding
.NET 3.5sp1 中指定,尽管它是可用的。这就是我通常指定这些类型的格式的方式:
<TextBlock Text="{Binding x, StringFormat={}{0} entities available.}" />
这使您的 ViewModel 仅指定显示所需的数据,并轻松地允许视图根据需要格式化数据。IMO,这是视图和视图模型之间最干净的分隔线。
请注意,需要 {} 来转义 {0},因为它是 StringFormat 属性之后的第一个元素。