Коллекции WPF и привязка данных - PullRequest
2 голосов
/ 09 января 2010

Я новичок в WPF и пытаюсь обернуть голову вокруг фреймворка WPF, что он делает и не делает для вас.

Чтобы прояснить это, я хотел бы знать, в чем разница между этим:

public List<MyCustomObject> MyCustomObjects
{
    get { return (List<MyCustomObject>)GetValue(MyCustomObjectsProperty); }
    set { SetValue(MyCustomObjectsProperty, value); }
}

public static readonly DependencyProperty MyCustomObjectsProperty =
    DependencyProperty.Register("MyCustomObjects", typeof(List<MyCustomObject>),
    typeof(Main), new UIPropertyMetadata(new List<MyCustomObject>()));



и это:

public ObservableCollection<MyCustomObject> MyCustomObjects { get; set; }

public Main ()
{
    MyCustomObjects = new ObservableCollection<<MyCustomObject>();
}

Ответы [ 4 ]

4 голосов
/ 09 января 2010

В дополнение к ответам Авиад и Рида я хотел бы указать на серьезную ошибку в вашем первом примере кода:

public static readonly DependencyProperty MyCustomObjectsProperty =
    DependencyProperty.Register("MyCustomObjects", typeof(List<MyCustomObject>),
    typeof(Main), new UIPropertyMetadata(new List<MyCustomObject>()));

new List<MyCustomObject>(), используемое в качестве значения по умолчанию , будет создано только один раз , поэтому по умолчанию все экземпляры вашего типа будут использовать один и тот же экземпляр List<MyCustomObject>, что, вероятно, не то, что вам нужно .. Единственное разумное значение по умолчанию здесь null

4 голосов
/ 09 января 2010

Хорошо, мы должны навести порядок в вещах, здесь есть несколько понятий, смешанных вместе.

Прежде всего, вы спрашиваете, в чем разница между полевым свойством и свойством зависимости. Google будет вашим лучшим другом, однако я рекомендую эту запись в блоге авангарда WPF Джоша Смита: Обзор свойств зависимостей в WPF

Вкратце: свойства зависимостей поддерживают богатство WPF: стили, анимация, привязка, метаданные и т. Д.

Во-вторых, вы спрашиваете, в чем разница между List и ObservableCollection. Ну, последний предоставляет уведомления об изменениях (в виде событий) о любых изменениях в коллекции (добавление, удаление, изменение порядка, очистка и т. Д.), А первый - нет. Вы можете прочитать больше об этом здесь: Класс ObservableCollection

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

2 голосов
/ 09 января 2010

В первом случае вы настраиваете свойство зависимости, содержащее экземпляр List<T>.

Во втором вы создаете обычное свойство CLR, но устанавливаете его как ObservableCollection<T>.

Для привязки данных WPF здесь есть некоторые различия.

Как правило, вы хотите, чтобы все ваши свойства в DataContext (который является объектом, с которым вещи «привязываются») по умолчанию либо реализовывали INotifyPropertyChanged, либо являлись свойством зависимости. Это позволяет платформе связывания знать, когда вносятся изменения в этот объект. Однако обычно вы используете свойство зависимости только в том случае, если вы работаете с настраиваемым элементом управления - обычно лучше иметь объект, к которому привязаны ваши данные, как отдельный класс, назначенный для DataContext. (Подробнее см. Джош Смит о MVVM или мой последний подробный пост о MVVM ...)

Однако для коллекции обычно требуется, чтобы система привязки знала, когда изменяются элементы в коллекции (т. Е. Добавляется элемент). ObservableCollection<T> обрабатывает это путем реализации INotifyCollectionChanged.

Используя второй подход (используя ObservableCollection<T>), ваш пользовательский интерфейс может сообщать, когда элементы были добавлены или удалены из коллекции, а не только когда назначена новая коллекция. Это позволяет всем работать автоматически, например, добавлять элементы ListBox при добавлении нового элемента в вашу коллекцию.

1 голос
/ 09 января 2010

1

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

MyCustomObjects.Add(new MyCustomObject()); //Wont update the view through databinding
MyCustomObjects = new List<MyCustomObject>(); //Will update the view through databinding

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

2

Вы используете наблюдаемую коллекцию, которая реализует для вас INotifyCollectionChanged, чтобы сообщать привязке данных всякий раз, когда изменяется содержимое коллекции. Это будет иметь противоположные последствия, чем # 1:

MyCustomObjects.Add(new MyCustomObject()); //Will update the view through databinding
MyCustomObjects = new ObservableCollection<MyCustomObject>(); //Won't update the view through databinding
...