Является ли использование преобразователей значений для создания строк, дружественных к GUI, неправильным использованием преобразователей значений?

В настоящее время я использую преобразователи значений для создания удобных для пользователя строк для графического интерфейса. В качестве примера у меня есть окно, которое отображает количество доступных объектов в строке состояния. Viewmodel просто имеет свойство зависимости int, которое может установить вызывающий код, а затем в привязке для текстового поля, отображающего количество объектов, я указываю свойство зависимости int и преобразователь значения, который заменяет "x" на "x доступных объектов". ".

Мой код начинает замусориваться этими конвертерами, и в моем XAML есть большое количество раздражающих объявлений ресурсов, и все же мне они нравятся, потому что все специфичные для GUI форматирования строк изолированы в конвертерах, а вызывающий код не ' не нужно беспокоиться об этом. Но все же, мне интересно, не для этой ли цели были созданы конвертеры значений.

3 ответа

Решение

Как уже упоминалось @slugster, StringFormat свойство может быть указано в Binding, хотя он доступен с.NET 3.5sp1. Вот как я обычно указываю эти типы форматов:

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

Это позволяет вашим ViewModels указывать только те данные, которые требуются для отображения, и легко позволяет представлению форматировать данные так, как они хотят. ИМО, это самая чистая линия разделения между представлением и моделью представления.

Обратите внимание, что {} требуется для экранирования {0}, поскольку это первый элемент после свойства StringFormat.

Это не "неправильно", если вы используете преобразователь значений для того, для чего он предназначен. Лично я использую их для преобразования значений перечисления в дружественные строки, но вместо жесткого кодирования строки в преобразователе значений VC использует значение перечисления для получения строки из файла ресурсов.

В конкретном случае, о котором вы упомянули, я бы поступил немного иначе, чтобы сократить количество венчурных капиталов, которые у вас есть - вы можете сделать это только одним. Что вы делаете, это подставляете / вставляете значение прямо в известную строку. Что вы можете сделать, это начать использовать ConverterParameter который доступен для вас, и используйте его для передачи идентификатора строки в файле ресурсов, затем значение, которое передается в 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 имеет возможность указывать строку формата как часть выражения привязки, это также может вам помочь.

Я обычно делаю этот вид преобразования в модели представления. Таким образом, модель представления будет иметь свойство зависимости строки, которое "украшает" базовое значение int.

Из вашего вопроса не ясно, как значение int обновляется в вашем сценарии, так что это может быть фактором при выборе правильного решения.

Использование модели представления для этого более выразительно, ИМХО - вы привязываетесь непосредственно к тому, что отображается, и ваша логика отображения (которую я бы хотел рассмотреть) не скрыта в конвертере, который вы можете найти только, просматривая XAML.

Другие вопросы по тегам