Thursday, September 10, 2009

Keeping the overview

The main window is getting into shape, but I do not like the Xaml code :-(. It's getting big, and I'm loosing the overview. Below is a small example of what I mean, the window just shows the CCNet project data, (name, description, ...) and a list of the issues (key, description, votes, ..)
<Window x:Class="JiraWpf.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lc="clr-namespace:JiraWpf"
Title="Window2" >
<Window.Resources>
<ObjectDataProvider x:Key="CCNetProject"
ObjectType="{x:Type lc:CCNetJiraDataProvider}"
MethodName="GetCCNetProject"
/>
<ObjectDataProvider x:Key="AllProjects"
ObjectType="{x:Type lc:CCNetJiraDataProvider}"
MethodName="GetProjects"
/>
<ObjectDataProvider x:Key="AllIssues"
ObjectType="{x:Type lc:CCNetJiraDataProvider}"
MethodName="GetIssuesFromFilter"
/>
<DataTemplate x:Key="IssueTemplate" >
<StackPanel Orientation="Horizontal" >
<Label Content="{Binding Key}" Width="200"/>
<Label Content="{Binding Description}" />
<Label Content="{Binding Votes}" />
<Label Content="{Binding Summary}" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<StackPanel>
<DockPanel>
<Expander VerticalContentAlignment="Center" DockPanel.Dock="Left" DataContext="{StaticResource CCNetProject}" >
<StackPanel Orientation="Vertical" >
<Label Content="{Binding Lead}" />
<Label Content="{Binding Key}" />
<Label Content="{Binding Description}" />
<Label Content="{Binding Name}" />
</StackPanel>
</Expander>
<ListBox DockPanel.Dock="Top"
ItemsSource="{Binding Source={StaticResource AllIssues}}"
ItemTemplate="{StaticResource IssueTemplate}"
/>
</DockPanel>
</StackPanel>
</Window>
As you can see, that is getting big, and it shows almost nothing :-( Time to clean house!
First thing I do not like is the difference of showing data between the listbox and the expander. I prefer the one of the listbox, where you say that the items have the specified template, leaving the actual layout out of the overview.
Downside is that Expander does not have an ItemTemplate property, and creating that property and functionality on all kind of controls does not sound as an attractive solution. The good news is that does exist already, WPF has this functionality build in : you just have to use basic controls and styles !
Now that is what I like : basic controls. Never thought that I would ever say : I like something about WPF ;-)
So I created a style that just sets the Control.Template property, this allows to easily create a visualisation of a certain item, the way like the it is done with a DataTemplate. And this style is applied to a ContentControl residing in the expander. This is already better, but now I have a style and a datatemplate to visualise data, and personally I do not like 2 ways of doing the same stuff in 1 program. So I changed the DataTemplate also into a style. This means that I have to use the ItemContainerStyle property in stead of the ItemTemplate in the listbox.
That being done, the way of presentation is more consistent, but the file is still rather big. It would be nice if the resources where moved into a separate file, or set of files, and luckily this is also supported out of the box with the ResourceDictionary.MergedDictionaries. Resulting in the following for the window.xaml
<Window x:Class="JiraWpf.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lc="clr-namespace:JiraWpf"
Title="Window1" >
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/DataProvider.xaml" />
<ResourceDictionary Source="Resources/DataLayout.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<DockPanel>
<Expander VerticalContentAlignment="Center" DockPanel.Dock="Left" DataContext="{StaticResource CCNetProject}" >
<ContentControl Style="{StaticResource CCNetProjectTemplate}" />
</Expander>

<ListBox DockPanel.Dock="Top"
ItemsSource="{Binding Source={StaticResource AllIssues}}"
ItemContainerStyle="{StaticResource IssueTemplate}"
/>
</DockPanel>
</StackPanel>
</Window>

As you can see, a lot shorter and more easily to follow. Below is the DataLayout.xaml file, I did not post the DataProvider.xaml file, because it is just a copy and paste of all the ObjectDataProviders into an empty ResourceDictionary file.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="CCNetProjectTemplate" >
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Vertical" >
<Label Content="{Binding Lead}" />
<Label Content="{Binding Key}" />
<Label Content="{Binding Description}" />
<Label Content="{Binding Name}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style x:Key="IssueTemplate" >
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Horizontal" >
<Label Content="{Binding Key}" Width="200"/>
<Label Content="{Binding Description}" />
<Label Content="{Binding Votes}" />
<Label Content="{Binding Summary}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>


Now this looks like it is more manageable. Stay tuned ...

No comments:

Post a Comment