3

I've written a date control that's used for displaying days for a variable range laid out by month. The days are designed to display a two-letter code for either the AM, PM or entire day and may have their backgrounds set to specific colours, for example:

Sample of the calendar

To get the days to be evenly spaced and to match the day number columns I've used a UniformGrid contained in a Stackpanel:

<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
                <ItemsControl Name="cal" ItemsSource="{Binding Days}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <UniformGrid  Rows="13" Columns="32" Margin="0,0,1,5" Width="1158" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <local:ucYearViewDay/>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>

The days are each a user control (that impliments INotifyPropertyChanged) I've designed that support showing AM, PM or full day codes. The days are then added to the ObservableCollection that the date control is bound to.

The Problem

All of the above set up work is done from calls in the constructor, when Form.Show() is called it takes about 10-12 seconds to render the form.

Research

I've spent a bit of time reading up on what I can do to speed this up but I don't seem to be able to find anything to help. I've tried setting the ItemsControl to make use of Virtualizing as suggested in this post but that's made no difference - as I understand I'd only get performance gains this way if I used a lot of scrolling and my control does not scroll. There is a guide on MSDN about improving WPF performance which I've been looking at, specifically the section on data binding but I didn't find anything that helped much.

Based on what I've said, are there any other techniques that I could employ to speed things up? I suppose I could do away with the binding and write to the controls directly but this would be a last resort.

Community
  • 1
  • 1
GrandMasterFlush
  • 6,269
  • 19
  • 81
  • 104

2 Answers2

1

VirtualizingStackPanel.IsVirtualizing="True" will work only when you set ItemPanel as VirtualizingStackPanel. You can improve the performance by writing Virtualized uniformGrid of your own. Refer the below link to know how to make virtualized Tile panel. In the same way, you can write your own panel which will improve performance.

http://blogs.msdn.com/dancre/archive/2006/02/06/implementing-a-virtualized-panel-in-wpf-avalon.aspx

Sivakumar
  • 478
  • 2
  • 13
  • 1
    Thanks, but my control doesn't use any scrolling. From what I can see in that article the performance gains from virtualising a control come from it using scrolling. – GrandMasterFlush Jul 24 '13 at 09:27
1

Based on @Erno de Weerd's suggestion of using some performance tools I had a hunt around and after reading this post about the performance tools available in VS2012 I used the 'Performance Analysis' option on the 'Analyze' menu and let a trace run.

The results were quite surprising to me. Whilst the loading of the calendar featured on the 'Functions Doing Most Individual Work' list they didn't really stand out. What was taking up all the time was a piece of code I initiated via Task.Factory.StartNew() that initiated a NamedPipeServerStream:

enter image description here

This code is used by an interface to check for incoming messages to another part of the application. Whilst I've not noticed it slowing down the application it seems that it reacts badly when the application is busy on WPF-related tasks. Removing this code means that the calendar control loads in less than two seconds. I'll be re-writing the offending code shortly.

So, lesson learnt: use performance tools. Thanks for all the comments, help and suggestions.

Community
  • 1
  • 1
GrandMasterFlush
  • 6,269
  • 19
  • 81
  • 104