WPF Elements: How to build a multi-scheduler

One of the controls you’ll find in Mindscape WPF Elements is the Scheduler which allows users to create, edit and manage their appointments. A single scheduler control can only display appointments for a single person. In this blog post we look at how to use some of the new parts that we provide to build up your own scheduler that can display schedules for different people simultaneously. This will be similar to what Microsoft Outlook 2010 provides as seen here:

Outlook 2010

By downloading the latest nightly build of WPF Elements, you’ll see there are some new controls at your disposal. The TimeOfDayBar is used to display each hour of the day in a vertical arrangement. The DaySchedule control displays appointments for a single day, and the DayScheduleSummary control displays appointments that are 24 hours or longer. The DaySchedule and DayScheduleSummary have their own properties for setting the current date and the schedule that they display. Each of these controls can be used by themselves allowing you to build them up in what ever arrangement you like. For this project, we want to display 3 different schedules side by side. Each schedule will be made up of the following parts: A header that displays a title and the current day, a DayScheduleSummary control and a DaySchedule control.

Step 1

The first thing that we need to do is build our own control that bundles these parts together. This will make them easier to use and style. I’ve called this the DayViewControl and it contains the following dependency properties:

  • Schedule: used to set the schedule that both the DaySchedule and DayScheduleSummary controls display.
  • Date: used to specify which day is being displayed.
  • Title: used to give each schedule its own name.
  • VerticalOffset: used to synchronize all the scroll bars together.

Step 2

Next we create a style for this custom control which colors and arranges all the parts however we like. This style also includes the DaySchedule and DayScheduleSummary controls and sets some of their properties as seen below.

<ms:DayScheduleSummary Schedule="{Binding Schedule, RelativeSource={RelativeSource TemplatedParent}}" Grid.Row="1"
                       Date="{Binding Date, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                       Name="PART_DayScheduleSummary" />
<ms:DaySchedule Grid.Row="2" Schedule="{Binding Schedule, RelativeSource={RelativeSource TemplatedParent}}"
                Date="{Binding Date, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                VerticalOffset="{Binding VerticalOffset, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
                Name="PART_DaySchedule" />

Here you can see we are binding the schedule and date properties of both these controls to the schedule and date of the DayViewControl. The binding for the date property is a two way binding because some of the features of the DaySchedule control can change the date internally. We are also binding the VerticalOffset property of the DaySchedule which aids in synchronizing the scroll bars across all the schedules.

Step 3

Within the application window, we can now place 3 instances of our DayViewControl side by side. To the left of these, we can place a TimeOfDayBar, and to the right will be a scroll bar. This arrangement can be seen in the following xaml:

<ms:TimeOfDayBar Margin="0,125,0,4" VerticalOffset="{Binding VerticalOffset, Mode=TwoWay, ElementName=Calendar1}" Name="TimeOfDayBar" />
<local:DayViewControl Style="{StaticResource DayViewControlStyle}" x:Name="Calendar1" Grid.Column="1" BorderBrush="#9CBF8B"
                      Background="#C1D8B7" Margin="0,0,6,0" Title="Ratchet" DateChanged="Calendar1_DateChanged" GotFocus="Calendar_GotFocus" />
<local:DayViewControl Style="{StaticResource DayViewControlStyle}" x:Name="Calendar2" Grid.Column="2" Margin="3,0,3,0" BorderBrush="#D195AA" Background="#E1BCC9"
                      Date="{Binding Date, ElementName=Calendar1, Mode=TwoWay}" VerticalOffset="{Binding VerticalOffset, Mode=TwoWay, ElementName=Calendar1}"
                      Title="Clank" GotFocus="Calendar_GotFocus" />
<local:DayViewControl Style="{StaticResource DayViewControlStyle}" x:Name="Calendar3" Grid.Column="3" BorderBrush="#8C8CD7" Margin="6,0,0,0" Background="#AFAFE4"
                      Date="{Binding Date, ElementName=Calendar1, Mode=TwoWay}" VerticalOffset="{Binding VerticalOffset, Mode=TwoWay, ElementName=Calendar1}"
                      Title="Dr. Nefarious" GotFocus="Calendar_GotFocus" />
<ScrollBar Maximum="{Binding ActualHeight, Converter={StaticResource ScrollBarMaximum}, RelativeSource={RelativeSource Self}}"
           SmallChange="30" LargeChange="30" ViewportSize="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
           Grid.Column="4" Value="{Binding VerticalOffset, Mode=TwoWay, ElementName=Calendar1}" Orientation="Vertical" Margin="0,126,0,0" />

Here you will notice that we are binding all the dates and vertical offsets of the DayViewControls together. The verticalOffset of the TimeOfDayBar and the ScrollBar are also bound together so that they all move as one.

And thats it

Overall, this produces the following result:

Ratchet and Clank Schedule

The source code for the full project can be downloaded here. Make sure you install the latest nightly build and include a reference to your copy of WPF Elements. The project also demonstrates how to use the SchedulerNavigationBar to change the current day, and how to only allow one appointment to be selected across all the DayViewControls. Using these new controls you can create all sort of scheduler arrangements, or generalize this sample to display a variable number of schedules.

If you need advice on building your own scheduler using WPF Elements, then leave a comment on this blog, or let us know in the forum.

Tagged as WPF, WPF Elements

8 Responses to “WPF Elements: How to build a multi-scheduler”

  • Our wish is your command! You guys are soooo awesome!!!

  • Thanks Peter – we aim to please :-)

  • […] alias errors in generated SQLWPF ElementsAdded controls for single-day display — see the multiple schedule sample hereFixed an issue where TimePicker wasn’t showing the current valueWPF DiagrammingFixed an issue […]

  • This is great. Any pointers for how I could extend this to:

    – Have a collection of DayViewSchedule’s bound to a collection of Schedule’s – depending on the date being displayed I need to display different schedules
    – bind the Schedule Items to the DayViewSchedule
    – allow a user to drag an item from one DayViewSchedule to another

  • Hello David

    For your first point, you will want to create a general version of what I have put together in this blog. In this blog, I have hard coded 3 DayViewControls into the application. You will want to do something like build your own control called MultiScheduler. This will contain a collection of Schedule objects. Then you can style this control to be populated with DayViewControls based on the schedule collection.

    For your second point, I’m not sure what you want here. ScheduleItems are given to the day view controls through the Schedule property.

    As for the last point, I’ll need to add some stuff on our side to get cross-schedule-dragging to be supported. I’ll see what I can come up with.

    Regards
    – Jason

  • Jason,
    Would you provide an example for using the recurrence dialog. When I try to use it, I get the following error.

    ‘StartTimeEditor_SelectedTimeChanged’ value cannot be assigned to property ‘SelectedTimeChanged’ of object ‘Mindscape.WpfElements.TimePicker’. Error binding to target method. Error at object ‘StartTimeEditor’ in markup file ‘Mindscape.WpfElements;component/scheduler/recurrencedialog.xaml’.

    I get this error when I try to initialize a new instance. I am trying to recreate the appointment dialog you have on your site. I am using Mindscape Elements version 4.

    Your help is greatly appreciated.

  • Hello Michael

    I have not been able to reproduce this error. But this is the code you can use to create and display the recurrence dialog:

    RecurrenceDialog dlg = new RecurrenceDialog(item, null, DayOfWeek.Monday);
    Window wnd = new Window();
    wnd.Title = “Appointment Recurrence”;
    wnd.ResizeMode = ResizeMode.NoResize;
    wnd.Content = dlg;
    wnd.Width = 520;
    wnd.Height = 450;
    wnd.ShowDialog();

    The item variable is an instance of the schedule item being created by your appointment dialog. This can not be null.

    If you are still having troubles getting this to work, come make a new thread on our forum: http://www.mindscapehq.com/forums/Forum.aspx?ForumID=15

  • Jason,

    Thanks for the code snippit. I installed the latest build and it seem to have fixed the problem. Thanks for your quick response.

  • Leave a Reply

Archives

Join our mailer

You should join our newsletter! Sent monthly:

Back to Top