Monday, March 23, 2009

Accordion is a fun control with a lot of properties and options. I had great fun building it and I hope you will have great fun while using it. This post gives an overview of the control. Next parts will look into other controls that are used with Accordion.

image

You can see a live demo here, or go to our sample browser (SL2, SL3) to play around with the control. I have a little ‘studio’ there, that will allow you to set some options and see how the control behaves.

The Accordion shown in the picture above is build like this:

  1     <layoutToolkit:Accordion x:Name="acc" Grid.Column="0" >
  2       <layoutToolkit:AccordionItem Content="item 1" Header="A"  />
  3       <layoutToolkit:AccordionItem Content="item 2" Header="B -  long header" />
  4       <system:String>regular string item 3</system:String>
5 </layoutToolkit:Accordion>

As you can see, three items are added. The first two are AccordionItems, allowing us to set a header and content. The last one is a String, which Accordion will wrap in an AccordionItem behind the scenes.

Accordion

Accordion can be best described as an ItemsControl that displays Expanders. The items shown are actually of type AccordionItem and can expand or collapse.
We use the paradigm of Selection, instead of Expanding/Collapsing, so from now on you will here me talk about a selected AccordionItem, which amounts to an expanded AccordionItem.

The Accordion class manages these AccordionItems and is responsible for the following:

  • Easily styling the AccordionItems (ItemContainerStyle)
  • Setting a default ContentTemplate and HeaderTemplate
  • Setting the ExpandDirection
  • Single select and multi select. Actually, Accordion allows a couple of SelectionModes that I will talk about
  • Managing a SelectedItem and SelectedIndex
  • Managing SelectedItems and SelectedIndices
  • Scheduling when a selected item is expanded or contracted (!)

Accordion manages AccordionItems just as ListBox would be managing ListBoxItems. Let’s first look at the concepts that you know from other ItemControls and see how Accordion handles them.

ItemTemplate versus ContentTemplate and HeaderTemplate

When an item is added to an ItemsControl, Accordion will check if it is already an instance of type AccordionItem. If it is not, the item will be wrapped inside an AccordionItem.
You might expect to be able to define how your item will look with an ItemTemplate, but that does not make that much sense, given that we expect you to want to set a header and a content separately.

Instead, Accordion exposes a ContentTemplate and HeaderTemplate DP. There is some talk to drop the ContentTemplate and just use the ItemTemplate for it, let me know what your thoughts on that are.

I do make sure that both Content and Header datacontext is set appropriately, so you might do something like this:

        <layoutToolkit:Accordion>
          <layoutToolkit:Accordion.ContentTemplate>
            <DataTemplate>
              <StackPanel Orientation="Horizontal">
                <TextBlock Text="Content:" />
                <TextBlock Text="{Binding}" />
              </StackPanel>
            </DataTemplate>
          </layoutToolkit:Accordion.ContentTemplate>
          
          <layoutToolkit:Accordion.HeaderTemplate>
            <DataTemplate>
              <StackPanel Orientation="Horizontal">
                <TextBlock Text="Header:" />
                <TextBlock Text="{Binding}" />
              </StackPanel>
            </DataTemplate>
          </layoutToolkit:Accordion.HeaderTemplate>
          
          <System:String>hello</System:String>
          <System:String>world</System:String>
</layoutToolkit:Accordion>

You would end up with an accordion that looks like:

image

In my opinion there are two main scenario’s to use an itemscontrol like Accordion:

  1. Bind to businessobjects: use ContentTemplate and HeaderTemplate to determine what is shown
  2. Set items inline: use AccordionItem directly.
Selection

An Accordion allows for the following SelectionModes: One, OneOrMore, ZeroOrOne and ZeroOrMore.

Since there can be more than 1 item selected, Accordion supplies a few properties (and events to match) to let you know what’s up:

  • SelectedItem: The selected item. If Accordion allows multiple items, this property will have the last selected item
  • SelectedIndex: The index of the selected item. This is necessary because you could have multiple AccordionItems based on the same item.
  • SelectedItems: A collection of all the items that are selected.
  • SelectedIndices: A collection of indexes.

By setting a SelectionMode, the behavior of Accordion is changed quite profoundly. When SelectionMode One or OneOrMore is chosen, Accordion will always make sure there is at least one AccordionItem selected. It does so by making it impossible to unselect an item if it is the last one selected. If no item is selected when the mode is set to One*, the first item in the list will be auto-selected.

ExpandDirection

You can specify in which direction the Accordion should open by setting an ExpandDirection (Left, Right, Up, Down). I’ll go in-depth in how you can template your AccordionItems appropriately. In the default template there is a little funky arrow that points to the content, that arrow is repositioned according to the ExpandDirection.

SelectionSequence

When the user selects an item, Accordion might have unselect another item (in the ZeroOrOne or One modes). The de-selection will happen immediate, however, Accordion gives you the option to influence when the actual animations happen. The SelectionSequence property takes values of 'CollapseBeforeExpand’ and ‘Simultaneous’.

The CollapseBeforeExpand mode will actually schedule collapse animations before expands. The effect is quite nice.

Please let us know if you are interested in different scheduling schema’s. I can for instance think of an Accordion that starts the next animation when it is halfway through the first one. Not sure if it looks good though!

The big one: Layout

Accordion will behave completely different when it has a fixed size versus no size. In the first case, the items will share all the space amongst each other that the parent has. In the latter, each item will take the space it desires.

I will revisit the layout topic more in-depth, because there are a few intricacies in how it works.

--------

Next parts will look at AccordionItem, ExpandableContentControl and LayoutTransformer.

Monday, March 23, 2009 3:29:56 AM (Romance Standard Time, UTC+01:00)
Good work. Could you release a talk about skinning the Accordion control? Would be nice to see different animations for the movement of arrows. Thanks.
shaggygi
Monday, March 23, 2009 4:33:58 AM (Romance Standard Time, UTC+01:00)
Thanks for the explanations...

...a little question concerning the layout:

Will the Accordion stretch dynamically to the available size given by its parent (let say it would be hostet in a Window)?
And if so, how does an AccordionItem behave in this case when it expands - will it fully strech as well to the available
size given by the Accorion?

Thanks in advance
Marc
Monday, March 23, 2009 4:35:02 AM (Romance Standard Time, UTC+01:00)
...well, and another one...
Can the control be used or ported to WPF?
Marc
Monday, March 23, 2009 6:04:16 AM (Romance Standard Time, UTC+01:00)
@shaggygi: yep, I plan on doing a full series on accordion, and I'll be sure to spend some extra time on that

@ Marc:
* yes to the layout question. If you give the accordion an alignment of stretch, the accordionitems will try to fill that space. If there is only one item, it will steal all room, if there are more items they will share evenly.
* unknown on the WPF question. There is a constraint in time obviously so letting us know that there is a need for this will help (hint: vote for it!). No promises ofcourse, but the team listens very closely to wishes coming from the community, like yours.
Ruurd
Monday, March 23, 2009 3:45:34 PM (Romance Standard Time, UTC+01:00)
Thanks for your reply.

Layout sounds great. I always found it very difficult to achieve that containers expand\stretch to the available size especially combined with animation if the "actual size" is kind of unknown prior to the animation. I am looking forward digging into the code and see how you achieved that. :-)

Regarding WPF: Is the current version of the control a) compatible with WPF b) if you won't be able to port it to WPF, is it allowed to use the code and try to port it myself? c) if so, how much effort would be required?
Marc
Monday, March 23, 2009 8:53:44 PM (Romance Standard Time, UTC+01:00)
Is there a project to download?
Fallon Massey
Tuesday, March 24, 2009 1:47:15 AM (Romance Standard Time, UTC+01:00)
Is it possible to make the Accordion's AccordionItems to be displayed side-by-side horizontally? Example: Could you have three AccordionItems horizontally ( All text displayed horizontally, as well ) and each AccordionItem include menu items for navigation that could expand vertically. This, of course, would include the Selection Mode for zero, one, or all to be opened at the time. Thanks.
shaggygi
Tuesday, March 24, 2009 4:10:19 AM (Romance Standard Time, UTC+01:00)
@Marc: I just look at the size the control wants to be, indeed it is more difficult when animating. I hope the code doesn't disappoint you ! :)
a) the current version is not byte compatible with WPF
b) if you want us to spend the time on converting it, please make yourself heard by making a workitem and getting some votes on it. We _do_ listen closely.
c) since SL is a subset of WPF, the changes that need to be made will be fairly trivial. However, I do rely on VSM heavily, which would mean the control needs a dependency on that.

@Fallon: sure! Accordion is part of the Silverlight Toolkit which you can download at www.codeplex.com/silverlight.

@shaggygi: great scenario. Accordion was not written to enable this but your best bet will be to look at the template of the AccordionItems. I will look at this when blogging about AccordionItem.
Ruurd
Tuesday, March 24, 2009 11:23:01 PM (Romance Standard Time, UTC+01:00)
How well do the header and content templates integrate with DataContext? I noticed in the Samples, they seem to always set ItemsSource directly as in:

accordionGeneratedContent.ItemsSource = data;

If I change it to this:

accordionGeneratedContent.DataContext = data;

and then bind ItemsSource, the content template still works but the header template fails.

Any thoughts would be appreciated, thanks!
MikeT
Wednesday, March 25, 2009 8:13:30 AM (Romance Standard Time, UTC+01:00)
Hi Mike,

I will look into that. It shouldn't be a problem, so I'd be interested to see why you are having problems with this scenario.

I'll report back,
Ruurd
Ruurd
Thursday, March 26, 2009 5:36:17 AM (Romance Standard Time, UTC+01:00)
Hi Mike,

Thanks for reporting that. The Header gets bound to DataContext, which turns out to be the complete datacontext, instead of the datacontext of the item. I will file a bug.

Ruurd
Ruurd
Thursday, March 26, 2009 5:37:21 AM (Romance Standard Time, UTC+01:00)
@shaggygi: AccordionItem does not allow a different ExpandDirectino than Accordion. You might want to issue a vote for it though!
Ruurd
Thursday, March 26, 2009 1:12:30 PM (Romance Standard Time, UTC+01:00)
How do you vote for issues and controls in SL toolkit?
shaggygi
Saturday, March 28, 2009 6:57:48 AM (Romance Standard Time, UTC+01:00)
@shaggygi: just go to our site: silverlight.codeplex.com and go to issues. Vote for the issues you see there or create a new one (with a good description and repro!).
One of the great things I've noticed about our team is how serious we take votes, so I really recommend you vote for issues that are important to you.
Ruurd
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):