Collapsible Categories and MVVM

Topics: Getting Started, UI Architecture
May 20, 2011 at 4:19 PM

Hi!

I have built a custom TreeView with Caliburn that looks something like this:

- Category1
       item1      |_____|
       item2      |_____|
- Category2
       item3       |_____|
       item4       |_____|

I can’t use the built in TreeView in combination with HierachicalDataTemplate since it does not work well with Tab and especially Shift+Tab so I figured I build my own.

The XAML looks something like this:

	<ItemsControl ItemsSource="{Binding Categories}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <StackPanel Orientation="Horizontal">
                            <Button Width="10" Height="10" Margin="5 5 5 5" />
                            <TextBlock Text="{Binding Name}" Margin="5 5 5 5" FontWeight="Bold" />
                        </StackPanel>
                        <ItemsControl ItemsSource="{Binding Items}">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal" Margin="25 0 0 0" >
                                        <TextBlock Text="{Binding Name}" Width="100" Margin="5 5 5 5" />
                                        <TextBox Text="{Binding Value}" Width="100" />
                                    </StackPanel>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

When I click the “-“ sign I would like the category to collapse, but there are several ways to achieve this and I just wonder which one you guys think is the best:

  1. One way would be to send an ActionMessage and include the StackPanel of that Category using $source and then just hide the StackPanel. I’ve heard though that it is considered bad practice to manipulate the graphical components directly in this manner.
  2. Another way would be to have a public bool Visibility property on my Category class. I then bind this property to the Visibility of the StackPanel. Whenever I click I send an ActionMessage and include the $dataContext. Since the data context is my Category class I can just set Visibility to false here. But my Category class is part of my Model and adding a Visibility property, which contains graphical data that will not be stored in the database, feels wrong.
  3. I could also create a CategoryViewModel and put my public bool Visibility here but it feels a bit excessive to have a ViewModel for such a small task. 

So, what do you think?

Thanx
/Mike