Я просто вхожу в курс дела на MVVM, но все примеры, которые я видел до сих пор, связывают средства управления Представлением с простыми non-WPF определенными типами данных, такими как строки и ints. Однако в нашем приложении я хочу смочь установить кисть границы кнопки на основе числа в Модели.
В данный момент я перевожу число в кисть в ViewModel для хранения Представления XAML только, но это правильно?
Мне не нравится помещать определенный код WPF в ViewModel, но одинаково мне не нравится идея поместить код - позади на моей панели View.
Который является лучшим способом?
Спасибо
В настоящий момент я перевожу число в кисть в ViewModel, чтобы сохранить только View XAML, но так ли это?
Нет, нет В самом деле.
В идеале, вы не должны использовать зависимости WPF в вашей ViewModel. Это помогает сделать ваше приложение более тестируемым, а также легко переводимым в Silverlight или другие технологии в будущем.
WPF предоставляет механизм именно для этого сценария: IValueConverter .Очень легко создать ValueConverter, который переводит целое число, строку или любой другой тип в кисть. В обзоре привязки данных показан пример преобразования цвета в кисть с использованием преобразователя значений.
Это намного лучший дизайн в долгосрочной перспективе ... «Кисти» и другие концепции WPF на самом деле являются частью представления - они не привязаны к вашей логике. Ваша ViewModel должна мыслить в терминах состояния , и ваше View должно переводить это состояние в определенный способ представления состояния.
Допустим, вы хотите использовать «красную» кисть для отображения ошибки. Вместо того, чтобы ViewModel отображал кисть, она должна предоставлять некоторый примитив (например, свойство bool), например IsInErrorState
. Представление должно решить, как это представить - будь то красная кисть, большое предупреждение и т. Д. Конвертеры позволяют этому происходить чисто XAML способом.
В вашем случае с ValueConverter просто. Поскольку вы переходите с Number -> Brush (хотя я бы рекомендовал использовать собственный Enum вместо int), вы можете просто сделать что-то вроде:
[ValueConversion(typeof(int), typeof(SolidColorBrush))]
public class IntToBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
int option = (int)value;
switch(option)
{
default:
return Brushes.Black;
case 1:
return Brushes.Red;
case 2:
return Brushes.Green;
// ...
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// No need to convert back in this case
throw new NotImplementedException();
}
}
Попробуйте настраиваемый ValueConverter.
Какова цель сохранения представления только XAML? Сохранение ViewModel в чистоте имеет смысл благодаря тестируемости и SoC. Но никакого внутреннего кода?