2011-04-14 5 views
6

J'ai un CustomControl qui contient une ListBox:WPF contrôle personnalisé: DependencyProperty de type Collection

<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> 

Je lie la ItemsSource avec une propriété dans le Code Derrière:

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)); 
      } 
     } 
    } 

Maintenant, dans mon MainWindow J'essaie de lier un ObservableCollection de "Articles" avec mon CustomControl et sa propriété de dépendance ListSource:

<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> 

Et l'erreur que je reçois:

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 dans le contrôle personnalisé Je ObservableCollection<Article> au lieu de ObservableCollection<object> cela fonctionne. Y a-t-il un moyen de lier DependencyProperty de mon Custom Control avec une ObservableCollection d'objets sans avoir à spécifier le type de l'objet?

+1

Vous n'avez pas besoin d'implémenter INotifyPropertyChanged sur DependencyProperties (ne devrait pas en fait), ni ** ** placer de code dans le setter d'un proeprty de dépendance. –

+0

@ H.B. Voulez-vous dire que la propriété de dépendance implémentera automatiquement les notifications de modification appropriées? Ou, suggérez-vous qu'il existe une meilleure alternative? – Rachael

+0

@ UB3571: Oui, ils implémentent des notifications de modification mais ils introduisent une affinité de threads. L'alternative est, comme je l'ai dit, 'INotifyPropertyChanged'. –

Répondre

5

Modifiez le type de ListSource à IEnumerable, puis vous pouvez lier à n'importe quelle collection.

+0

Merci pour la réponse rapide, vous avez totalement sauvé la journée. – Aris

+0

En fonction de cet article de blog, vous devriez utiliser IList pour que vous puissiez aussi y ajouter xaml. http://sshumakov.com/2012/11/13/how-to-create-dependency-properties-for-collections/ –

Questions connexes