DependencyProperty getter / setter не вызывается

Я пытаюсь создать пользовательский элемент управления, полученный из стандартной сетки. Я добавил ObservableCollection как DependencyProperty настраиваемого элемента управления. Однако get / set этого никогда не достигается. Могу ли я получить некоторые рекомендации по созданию DependencyProperty, который работает правильно и ObservableCollection?

public class MyGrid : Grid { public ObservableCollection Items { get { return (ObservableCollection)GetValue(ItemsProperty); } set { SetValue(ItemsProperty, value); } } public static DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(ObservableCollection), typeof(MyGrid), new UIPropertyMetadata(null, OnItemsChanged)); } 

Я бы предложил не использовать ObservableCollection как тип свойства зависимостей Items .

Причиной наличия ObservableCollection здесь (я думаю) является включение UserControl для присоединения обработчика CollectionChanged при назначении значения свойства. Но ObservableCollection слишком специфичен.

Подход в WPF (например, в ItemsControl.ItemsSource ) заключается в том, чтобы определить очень простой тип интерфейса (например, IEnumerable ), а когда ему присваивается значение, выясните, реализует ли набор значений некоторые более конкретные интерфейсы. Это, по крайней мере, было бы здесь INotifyCollectionChanged , но коллекция также может реализовывать ICollectionView и INotifyPropertyChanged . Все эти интерфейсы не будут обязательными, и это позволит вашему свойству зависимостей связываться со всеми типами коллекций, начиная с простого массива и до сложного ItemCollection .

OnItemsChanged ваш OnItemsChanged вызов изменения свойства OnItemsChanged будет выглядеть следующим образом:

 private static void OnItemsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { MyGrid grid = obj as MyGrid; if (grid != null) { var oldCollectionChanged = e.OldValue as INotifyCollectionChanged; var newCollectionChanged = e.NewValue as INotifyCollectionChanged; if (oldCollectionChanged != null) { oldCollectionChanged.CollectionChanged -= grid.OnItemsCollectionChanged; } if (newCollectionChanged != null) { newCollectionChanged.CollectionChanged += grid.OnItemsCollectionChanged; // in addition to adding a CollectionChanged handler // any already existing collection elements should be processed here } } } private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { // handle collection changes here } 

Механизм привязки WPF может обойти ваше стандартное свойство CLR и перейти непосредственно к аксессуарам свойств зависимостей ( GetValue и SetValue ).

Вот почему логику не следует размещать внутри свойства CLR, а вместо этого внутри измененного обработчика.

Также ObservableCollection никогда не будет установлен, потому что, когда вы используете свойства коллекции из XAML, например:

   First Item Second Item   

Это на самом деле вызов get on Items а затем вызов Add для каждого из элементов.

Давайте будем гением компьютера.