DependencyProperty getter / setter no se llama

Intento crear un control personalizado derivado de una Grilla estándar. Agregué un ObservableCollection como DependencyProperty del control personalizado. Sin embargo, el get / set nunca se alcanza. ¿Puedo obtener algunas pautas para crear DependencyProperty que funcione correctamente con y 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)); } 

Sugeriría que no se use ObservableCollection como el tipo de una propiedad de dependencia de Items .

El motivo para tener aquí una ObservableCollection (supongo) es habilitar UserControl para adjuntar un controlador CollectionChanged cuando se asigna el valor de la propiedad. Pero ObservableCollection es demasiado específico.

El enfoque en WPF (por ejemplo, en ItemsControl.ItemsSource ) es definir un tipo de interfaz muy básico (como IEnumerable ) y cuando a la propiedad se le asigna un valor, averigüe si la colección de valores implementa ciertas interfaces más específicas. Esto al menos sería INotifyCollectionChanged aquí, pero la colección también podría implementar ICollectionView e INotifyPropertyChanged . Todas estas interfaces no serían obligatorias y eso permitiría que su propiedad de dependencia se vincule a todo tipo de colecciones, comenzando con una matriz simple hasta una colección de elementos compleja.

OnItemsChanged callback de cambio de propiedad OnItemsChanged se vería así:

 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 } 

El mecanismo de enlace de WPF puede omitir su propiedad de CLR estándar e ir directamente a los SetValue acceso de propiedad de dependencia ( GetValue y SetValue ).

Es por eso que no se debe colocar la lógica dentro de la propiedad CLR, sino dentro de un manejador modificado.

Además, la ObservableCollection nunca se establecerá porque cuando usa propiedades de colección de XAML, como las siguientes:

   First Item Second Item   

En realidad, está llamando a Items y luego a Add por cada uno de los elementos.