2011-04-14 31 views
6

Tengo un CustomControl que contiene una ListBox:WPF Control personalizado: DependencyProperty de tipo Colección

<UserControl x:Class="WpfApplication1.CustomList" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Grid> 
     <ListBox Name="listBox1" ItemsSource="{Binding ListSource}" /> 
    </Grid> 
</UserControl> 

Ato el ItemsSource con una propiedad en el código subyacente:

public partial class CustomList : UserControl, INotifyPropertyChanged 
    { 
     public CustomList() 
     { 
      InitializeComponent(); 
     } 

     public ObservableCollection<object> ListSource 
     { 
      get 
      { 
       return (ObservableCollection<object>)GetValue(ListSourceProperty); 
      } 
      set 
      { 
       base.SetValue(CustomList.ListSourceProperty, value); 
       NotifyPropertyChanged("ListSource"); 
      } 
     } 

     public static DependencyProperty ListSourceProperty = DependencyProperty.Register(
      "ListSource", 
      typeof(ObservableCollection<object>), 
      typeof(CustomList), 
      new PropertyMetadata(OnValueChanged)); 

     private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      ((CustomList)d).ListSource = (ObservableCollection<object>)e.NewValue; 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     public void NotifyPropertyChanged(string propertyName) 
     { 
      if(PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 

Ahora en mi MainWindow Intento vincular un ObservableCollection de "Artículos" con mi CustomControl y su ListSource DependencyProperty:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:local="clr-namespace:WpfApplication1" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     DataContext="{Binding RelativeSource={RelativeSource Self}}" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <local:CustomList ListSource="{Binding Articles}"/> 
    </Grid> 
</Window> 

Y el error que consigo:

Error: 1 : Cannot create default converter to perform 'one-way' conversions between types 'System.Collections.ObjectModel.ObservableCollection`1[WpfApplication1.Article]' and 'System.Collections.ObjectModel.ObservableCollection`1[System.Object]' 

Si en el control personalizado Tengo ObservableCollection<Article> en lugar de ObservableCollection<object> funciona. Entonces, ¿hay alguna forma de vincular la propiedad DependencyProperty de mi Custom Control con una ObservableCollection de objetos sin tener que especificar el tipo de objeto?

+1

No necesita (de hecho no debería) implementar INotifyPropertyChanged en DependencyProperties, también ** no ** colocar ningún código en el setter de una propiedad de dependencia. –

+0

@ H.B. ¿Estás diciendo que la propiedad de dependencia implementará automáticamente las notificaciones de cambio adecuadas? ¿O está sugiriendo que hay una mejor alternativa? – Rachael

+0

@ UB3571: Sí, sí implementan notificaciones de cambio pero introducen afinidad de subprocesos. La alternativa es, como dije, 'INotifyPropertyChanged'. –

Respuesta

5

Cambie el tipo de ListSource a IEnumerable, luego puede enlazar a cualquier colección.

+0

Gracias por la respuesta rápida, has salvado totalmente el día. – Aris

+0

De acuerdo con esta publicación del blog, debes usar IList para que puedas poblar en tirar xaml también. http://sshumakov.com/2012/11/13/how-to-create-dependency-properties-for-collections/ –

Cuestiones relacionadas