Это только я или WPF - беспорядок привязки данных и пользовательских IValueConverters? - PullRequest
7 голосов
/ 19 июля 2009

Серьезно, похоже, что каждый раз, когда я хочу, чтобы мои элементы пользовательского интерфейса общались друг с другом, я заканчивал тем, что кодировал новый, собственный, IValueConverter :(. Кто-то сказал мне, что я делаю это неправильно, пожалуйста!

Примеры:

  • Я хотел, чтобы кнопка была включена, только если мое текстовое поле содержало действительный URI. Отлично, время кодировать UriIsValidConverter!
  • Ой, я также хотел отключить его, пока я что-то обрабатываю. Я думаю, теперь мне нужно кодировать UriIsValidAndBoolIsFalseMultiConverter!
  • Я хочу отобразить список файлов в определенном каталоге (указанном в текстовом поле) внутри списка. Я думаю, мне нужен конвертер DirectoryPathToFileList!
  • О, я хочу значки для каждого из этих файлов в списке. Время для FileInfoToBitmap конвертера!
  • Я хочу, чтобы мой статус был красным, если моя строка состояния содержит «Ошибка», и зеленым в противном случае. Я могу закодировать StatusStringToSolidColorBrushConverter!

Я действительно думаю, что это не намного лучше, чем старый метод Windows Forms - просто соединить все вручную, используя события TextChanged (или что-то еще). Который я думаю, все еще вариант. Возможно, это то, что люди на самом деле делают, и я слишком стараюсь, чтобы все вписалось в парадигму привязки данных?

Так что да, пожалуйста, скажите мне, действительно ли это так, как WPF-кодирование - или я делаю это неправильно, и если да, то, что я должен делать.

Ответы [ 3 ]

10 голосов
/ 19 июля 2009

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

По шаблону MVVM ваш XAML (представление) просто содержит очень простые привязки данных в ViewModel, которая обрабатывает всю логику и обновляет представление через интерфейс INotifyPropertyChanged. Код для вашего третьего примера может выглядеть примерно так:

public class DirectoryManagerViewModel : INotifyPropertyChanged
{
    private string _directory;

    public string Directory
    {
        get { reutrn _directory; }
        set
        {
            if (_directory != value)
            {
                 _directory = value;
                 OnPropertyChanged("Directory");
                 if (IsValidDirectory(value))
                 {
                     PopulateFiles();
                 }
            }
        }
    }

    public ObservableCollection<FileViewModel> Files { get; private set; }

    private bool IsValidDirectory(string directory)
    {
          //return if the directory exists etc.
    }

    private bool PopulateFiles()
    {
         //Populate Files with files in directory
    }
}

Где FileViewModel - другая модель представления, которая содержит имя и значок для файла.

Преимущество этого подхода состоит в том, что ViewModels можно повторно использовать с другими представлениями и другими технологиями, такими как ASP.NET или Winforms, чтобы вы не были заблокированы в стеке WPF. (Если вы работаете в среде, где есть дизайнеры, отвечающие за внешний вид, и разработчики, отвечающие за поведение, это помогает определить эти границы)

В конце концов, хотя эта логика и должна куда-то идти, и хотя есть лучшие и худшие способы для разработки вашего приложения, вы все равно будете писать код, который принимает строку и преобразует ее в серию имен файлов и иконки где-то.

6 голосов
/ 19 июля 2009

Во-первых, вы можете начать с чтения шаблона Model-View-ViewModel (MVVM). Джош Смит недавно опубликовал фантастическую статью в журнале MSDN. MVVM и WPF отлично сочетаются. Сделано правильно, вам не нужно нужно IValueConverters столько . То, как вы делаете это сейчас, вызывает очень тесную связь между вашей визуализацией и действиями вашего приложения. MVVM предназначен для развязки этих элементов.

В этом контексте ваша модель представления будет отслеживать состояние для вас. Ваша кнопка будет включена, если метод CanExecute для определенного ICommand в вашей модели представления вернет true. Эта же концепция может обрабатывать отключение кнопки при обработке чего-либо.

Вы хотите отобразить список файлов в определенном каталоге, который указан внутри списка? Имейте DirectoryViewModel модель представления, которая будет обрабатывать предоставление списка файлов для представления путем привязки к модели представления. Отображение файлов можно указать с помощью DataTemplate, указанного в XAML, без кода. Эта же концепция может использоваться для предоставления значков представлению, отображение которого можно указать в шаблоне.

Вы хотите, чтобы ваш статус был красным, если сообщение о состоянии содержит «Ошибка» и зеленым в противном случае? Позвольте модели представления обрабатывать определение состояния, и пусть представление привязывается к этому состоянию, и теперь вам нужно всего лишь IStateConverter, чтобы соответствующим образом преобразовать состояние в красное или зеленое (это один из многих способов справиться с этой проблемой в контексте MVVM) .

Привыкайте хранить данные и состояние отдельно от вашего представления, и ваши приложения будут слабо связаны, их будет легче разрабатывать и обслуживать, а также будет легче тестировать.

5 голосов
/ 19 июля 2009

Не знаю, если вы не правы, просто сделать это намного сложнее, чем должно быть!

Я использую MVVM, поэтому, когда вы пишете конвертеры для клиентов, я предоставляю привязываемое свойство для модели представления, которое сообщает представлению, что делать. Например:

  1. Для отображения списка файлов я предоставляю коллекцию, которая содержит этот список.
  2. Если я хочу значки, объект в этой коллекции имеет свойство icon
  3. Если я хочу, чтобы статус был красным или зеленым, я предоставляю свойство StatusColorbrush.

Перемещая эту логику в модель представления, я получаю:

  1. намного проще, Xaml.
  2. может проверить мою логику представления без представления.

Этот подход использует одну из сильных сторон WPF - возможности связывания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...