2011-03-02 5 views
0

J'essaie de créer un contrôle Tag Cloud personnalisé. La façon dont il est censé fonctionner est que l'utilisateur peut lui donner une collection de chaînes dans la source items et la chaîne convertie sera affichée dans l'interface utilisateur. Le problème est lorsque j'essaie de supprimer le contrôle dans une application, j'obtiens l'erreur suivante: "Impossible de créer une instance de type TagCloudControl". Quelqu'un peut-il aider?Erreur WPF: Impossible de créer une instance de type ... lors de la création d'un contrôle personnalisé

code derrière

public class TagCloudControl : ListBox 
{ 
    static TagCloudControl() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(TagCloudControl), new FrameworkPropertyMetadata 
      (typeof(TagCloudControl))); 
    } 
    //tags dependency property 
    public static DependencyProperty TagsProperty = DependencyProperty.Register("Tags", 
     typeof(IEnumerable<Tag>), 
     typeof(TagCloudControl)); 

    public CollectionView GroupedTagsView { get; set; } 

    public TagCloudControl() 
    { 
     ItemsSource = Tags; 

     //group my tags by "name" property 
     GroupedTagsView = (ListCollectionView)CollectionViewSource.GetDefaultView(Tags); 
     GroupedTagsView.GroupDescriptions.Add(new PropertyGroupDescription("Name")); 

    } 

    public IEnumerable<Tag> Tags 
    { 
     get { return (IEnumerable<Tag>)GetValue(TagsProperty); } 
     set { SetValue(TagsProperty, value); } 
    } 
} 

XAML

<Window x:Class="TagCloudDemo.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:src="clr-namespace:TagCloudControlLibrary;assembly=TagCloudControlLibrary" 
Title="Window1" Height="300" Width="300"> 
<Grid> 

    <src:TagCloudControl HorizontalAlignment="Center" VerticalAlignment="Center" Name="firstTag"/> 

</Grid> 
</Window> 

TagControl XAML

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:TagCloudControlLibrary"> 

<local:CountToBrushConverter x:Key="CountToBrushConverter"/> 
<local:CountToFontSizeConverter x:Key="CountToFontSizeConverter"/> 

<Style TargetType="{x:Type local:TagCloudControl}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:TagCloudControl}"> 
       <Grid> 
        <WrapPanel Orientation="Horizontal" 
           Margin="2" 
           IsItemsHost="True"> 
        </WrapPanel> 

       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

<DataTemplate x:Key="TagsTemplate"> 
    <WrapPanel> 
     <TextBlock Text="{Binding Name}" 
        FontSize="{Binding ItemCount, Converter={StaticResource CountToBrushConverter}}" 
        Foreground="{Binding ItemCount, Converter={StaticResource CountToFontSizeConverter}}"/> 
    </WrapPanel> 
</DataTemplate> 
</ResourceDictionary> 

Tag classe

public class Tag 
{ 
    public Tag(string name) 
    { 
     Name = name;   
    } 

    public string Name { get; set;} 

} 

Répondre

0

Avez-vous besoin d'instancier mots clés?

Je suppose qu'il s'agit d'une exception de référence nulle, vous définissez la source de vos éléments en tant que balises dans votre constructeur, mais vous n'avez pas de balises instanciées.

public TagCloudControl() 
{ 
    Tags = new ObservableCollection<Tags>(); 

    ItemsSource = Tags; 
    ... 
} 

Edit:

Après avoir joué avec le code ... Je pense que les balises peut-être pas besoin d'être un DependencyProperty. Il semble que vous souhaitez associer le ItemsSource à ... Mots mais vous pouvez juste faire une simple propriété Mots clés, et, définissez le ItemsSource à la valeur passée:

public TagCloudControl() 
{ 
    //this is now empty. 
} 

public IEnumerable<Tag> Tags 
{ 
    get { return (this.ItemsSource as IEnumerable<Tag>); } 
    set { this.ItemsSource = value; } 
} 

Aussi je pense que votre style pourrait vouloir pour être plus comme ceci:

<Style TargetType="{x:Type local:TagCloudControl}"> 
    <Setter Property="ItemTemplate"> 
     <Setter.Value> 
      <DataTemplate DataType="{x:Type local:Tag}"> 
       <TextBlock Text="{Binding Name}" 
          FontSize="{Binding ItemCount, Converter={StaticResource CountToBrushConverter}}" 
          Foreground="{Binding ItemCount, Converter={StaticResource CountToFontSizeConverter}}"> 
      </DataTemplate> 
     </Setter.Value> 
    </Setter> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:TagCloudControl}"> 
       <Grid> 
        <WrapPanel Orientation="Horizontal" Margin="2" IsItemsHost="True"> 
        </WrapPanel> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Et enfin, je pense que vous pourriez manquer ItemCount dans votre classe «Tag».

+0

Ah comment ferais-je cela? – Ben

+0

Merci, j'ai l'erreur "une nouvelle expression nécessite() après le type" – Ben

+0

Ouais ... j'ai oublié le() ... J'ai modifié pour mettre à jour. (Aussi, vous voudrez enlever les '**' aussi bien). Et ça ne peut pas être juste IEnumerable. Cela devrait être un type spécifique qui implémente IEnumerable. – Scott

Questions connexes