Является ли использование преобразователей значений для создания строк, дружественных к 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.