Search code examples
wpfxamltag-cloud

Building a tag cloud in WPF


I'm trying to build a tag cloud in WPF based on an existing implementation [Download Source]. I didn't understand completely the implementation and my problem is, that instead of having the FontSize binded to the number of items in a collection, I want to bind it to some other values contained in a class. So in this part here,

FontSize="{Binding Path=ItemCount, Converter={StaticResource CountToFontSizeConverter}}"

I want to bind the FontSize to something else. How do I do that? Where does ItemCount belong to?

Thanks


Solution

  • ItemCount belongs to the group inside the collection view that is generated from that Tag.

    e.g. if i have a list

    A A B B B C

    And i group them i get:

    Group A : ItemCount = 2
    Group B : ItemCount = 3
    Group C : ItemCount = 1

    The whole point of a Tag-Cloud is to bind to that very property because you want to visualize how often a certain tag is used.


    To respond to your comments, the bare-bones setup should be something like this:

    <ItemsControl ItemsSource="{Binding Data}">
        <ItemsControl.Resources>
            <vc:CountToFontSizeConverter x:Key="CountToFontSizeConverter"/>
        </ItemsControl.Resources>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" Margin="2"
                           FontSize="{Binding Count, Converter={StaticResource CountToFontSizeConverter}}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    

    I assume that your data-object class exposes the properties Name and Count, to make sure that the size changes as count goes up that data-object class needs to implement INotifyPropertyChanged, that is about all there is to it.

    public class Tag : INotifyPropertyChanged
    {
        private string _name = null;
        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    OnPropertyChanged("Name");
                }
            }
        }
    
        private int _count = 0;
        public int Count
        {
            get { return _count; }
            set
            {
                if (_count != value)
                {
                    _count = value;
                    OnPropertyChanged("Count");
                }
            }
        }
    
        //...
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }