2008-12-10 4 views
6

Le code XAML suivant (ci-dessous) définit une collection personnalisée dans les ressources et tente de la remplir avec un objet personnalisé;Comment résoudre l'erreur WPF Designer 'Le type {0} ne prend pas en charge le contenu direct'. '?

<UserControl x:Class="ImageListView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="300" Height="300" 
    xmlns:local="clr-namespace:MyControls" > 
    <UserControl.Resources> 
     <local:MyCustomCollection x:Key="MyKey"> 
      <local:MyCustomItem> 
      </local:MyCustomItem> 
     </local:MyCustomCollection> 
    </UserControl.Resources> 
</UserControl> 

Le problème est que je reçois une erreur dans le concepteur de « Le type « MyCustomCollection » ne supporte pas le contenu direct ». J'ai essayé de définir ContentProperty comme conseillé dans MSDN, mais je ne peux pas savoir à quoi définir. L'objet de collection personnalisé que j'utilise est ci-dessous et est très simple. J'ai essayé Item, Items et MyCustomItem et ne peux pas penser à quoi d'autre essayer.

<ContentProperty("WhatGoesHere?")> _ 
Public Class MyCustomCollection 
    Inherits ObservableCollection(Of MyCustomItem) 
End Class 

Tous les indices sur l'endroit où je me trompe seraient reçus avec reconnaissance. Des conseils sur la façon de creuser dans le modèle d'objet WPF pour voir quelles propriétés sont exposées au moment de l'exécution, je pourrais être en mesure de le comprendre aussi.

Cordialement

Ryan

Répondre

5

Vous devez initialiser le ContentPropertyAttribute avec le nom de la propriété qui va représenter le contenu de votre classe. Dans votre cas, puisque vous héritez de ObservableCollection, il s'agira de la propriété Items. Malheureusement, la propriété Items est en lecture seule et ce n'est pas autorisé, car la propriété Content doit avoir un setter. Vous devez donc définir une propriété d'emballage personnalisé autour des articles et l'utiliser dans votre attribut - comme ceci:

public class MyCustomItem 
{ } 

[ContentProperty("MyItems")] 
public class MyCustomCollection : ObservableCollection<MyCustomItem> 
{ 
    public IList<MyCustomItem> MyItems 
    { 
     get { return Items; } 
     set 
     { 
      foreach (MyCustomItem item in value) 
      { 
       Items.Add(item); 
      } 
     } 
    } 
} 

Et vous devriez être bien. Désolé de faire ça en C# quand votre exemple est en VB, mais je crains vraiment VB et je n'arrive pas à obtenir une chose aussi simple ... Bref, c'est un jeu d'enfant de la convertir, donc - j'espère que ça aide.

+0

Ça a l'air bien, mais une question sur votre setter là-bas. Cela ne ferait-il pas continuellement ajouter à la collection et provoquer une exception? Aussi, pourquoi IList et non ObservableCollection? Merci –

+0

Non, il ajoutera seulement autant d'éléments que vous avez dans la variable de valeur entrante - et ce sont les valeurs que vous définissez en XAML. Et c'est IList , parce que c'est le type de la propriété Items. Rappelez-vous, le wrapper est pour la propriété Items, pas pour la classe entière. – Boyan

+0

Merci, c'est un excellent conseil. Très appréciée. –