Куда я должен поместить определенный код WPF при использовании MVVM?

Я просто вхожу в курс дела на MVVM, но все примеры, которые я видел до сих пор, связывают средства управления Представлением с простыми non-WPF определенными типами данных, такими как строки и ints. Однако в нашем приложении я хочу смочь установить кисть границы кнопки на основе числа в Модели.

В данный момент я перевожу число в кисть в ViewModel для хранения Представления XAML только, но это правильно?

Мне не нравится помещать определенный код WPF в ViewModel, но одинаково мне не нравится идея поместить код - позади на моей панели View.

Который является лучшим способом?

Спасибо

7
задан Surfbutler 16 April 2010 в 16:58
поделиться

2 ответа

В настоящий момент я перевожу число в кисть в 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();
    }
}
7
ответ дан 7 December 2019 в 03:13
поделиться

Попробуйте настраиваемый ValueConverter.

Какова цель сохранения представления только XAML? Сохранение ViewModel в чистоте имеет смысл благодаря тестируемости и SoC. Но никакого внутреннего кода?

2
ответ дан 7 December 2019 в 03:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: