使用值转换器生成 GUI 友好的字符串是否是对值转换器的滥用?

发布于 2024-08-27 21:32:20 字数 269 浏览 6 评论 0原文

目前,我使用值转换器为 GUI 生成用户友好的字符串。例如,我有一个窗口,在状态栏中显示可用实体的数量。 Viewmodel 只是有一个调用代码可以设置的 int 依赖属性,然后在显示实体数量的文本框的绑定上,我指定了 int 依赖属性和一个将“x”更改为“x 个可用实体”的值转换器”。

我的代码开始充斥着这些转换器,并且我的 XAML 中有大量烦人的资源声明,但我喜欢它们,因为所有特定于 GUI 的字符串格式都在转换器中隔离,并且调用代码不会这样做。不必担心。但我仍然想知道这是否不是价值转换器的目的。

Currently, I use value converters to generate user-friendly strings for the GUI. As an example, I have a window that displays the number of available entities in the status bar. The Viewmodel simply has an int dependency property that the calling code can set, and then on the binding for the textbox that displays the number of entities, I specify the int dependency property and a value converter that changes "x" into "x entities available".

My code is starting to become littered with these converters, and I have a large number of annoying resource declarations in my XAML, and yet I like them because all the GUI-specific string formatting is being isolated in the converters and the calling code doesn't have to worry about it. But still, I wonder if this is not the purpose that value converters were made for.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

歌枕肩 2024-09-03 21:32:20

如果您按照设计目的使用 valueconverter,那么这并不是“错误”。就我个人而言,我使用它们将枚举值转换为友好的字符串,但 VC 没有将字符串硬编码到值转换器中,而是使用枚举值从资源文件中获取字符串。

在你提到的具体情况下,我会做一些不同的事情来减少你拥有的风险投资的数量——你可以只用一个来做到这一点。您正在做的是将值直接替换/插入到已知字符串中。您可以做的是开始使用可用的 ConverterParameter ,并使用它来传递资源文件中字符串的 ID,然后可以插入传递到 VC 的值到由 VC 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 它能够指定格式字符串作为绑定表达式的一部分,这也可能对您有帮助。

It's not "wrong" if you are using the valueconverter for what it is designed to do. Personally i use them to translate enum values to friendly strings, but rather than hard coding the string in to the value converter the VC uses the enum value to source the string from a resource file.

In the specific case you mention, i would do things a little differently to cut down on the amount of VC's you have - you can do it with just one. What you are doing is substituting/inserting the value straight into a known string. What you can do is start using the ConverterParameter that is available to you, and use it to pass the ID of a string in your resource file, the value that is passed in to the VC can then be inserted into the string specified by the VCs ConverterParameter. Here is a quick pseudo code example:

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;
}

And you would use this converter like this:

<TextBlock Text={Binding someNumericValue, Converter={StaticResource MyConverter}, ConverterParameter=[key_to_resource_string]} />

Also have a look at WPF4 - IIRC it has an ability to be able to specify a format string as part of the binding expression, this may help you as well.

自由如风 2024-09-03 21:32:20

正如 @slugster 提到的,StringFormat 属性可以在 Binding 中指定,尽管它从 .NET 3.5sp1 开始可用。这就是我通常指定这些类型的格式的方式:

<TextBlock Text="{Binding x, StringFormat={}{0} entities available.}" />

这使您的 ViewModel 能够仅指定显示所需的数据,并轻松地允许视图根据需要格式化数据。 IMO,这是视图和视图模型之间最清晰的分隔线。

请注意,需要使用 {} 对 {0} 进行转义,因为它是 StringFormat 属性之后的第一个元素。

As @slugster mentioned, the StringFormat property can be specified in the Binding, although it is available as of .NET 3.5sp1. This is how I typically specify these types of formats:

<TextBlock Text="{Binding x, StringFormat={}{0} entities available.}" />

This enables your ViewModels to only specify the data that is required to display, and easily allows the view to format the data however it wants. IMO, this is the cleanest line of separation between the view and the viewmodel.

Note that the {} is required to escape the {0} as it is the first element after the StringFormat property.

拧巴小姐 2024-09-03 21:32:20

我一般在视图模型中进行这种转换。因此视图模型将有一个字符串依赖属性,它“装饰”底层的 int 值。

从您的问题中不清楚 int 值如何在您的场景中更新,因此这可能是选择正确解决方案的一个因素。

恕我直言,使用视图模型更具表现力——您直接绑定到正在显示的内容,并且您的显示逻辑(我认为是这样)不会隐藏在转换器中,您只能通过查看来找到它XAML。

I generally do this kind of conversion in the view model. So the view model will have a string dependency property, which "decorates" the underlying int value.

It's not clear from your question how the int value gets updated in your scenario, so that may be a factor in choosing the right solution.

Using the view model for this is more expressive IMHO--you are binding directly to what is being displayed, and your display logic (which I what I would consider it) is not buried in a converter that you can only find by looking through the XAML.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文