Showing posts with label Expander. Show all posts
Showing posts with label Expander. Show all posts

Nov 26, 2008

Customize Silverlight Toolkit Controls: Expander

Introduction

This is the second post of the Customize Silverlight Toolkit Controls series. This post demonstrates how to customize Expander, and provides the most asked customizations from Silverlight Toolkit forum.

Expander Customization

To customize Expander, it is very important to understand its API and default template, and know how to use Blend to re-template a control. I'd highly recommend you read my previous post Expander Control in Silverlight Toolkit if you haven't yet. The key to customize Expander:

  • understand Expander interface, especially its control contract:
    • Expander expects one template part, a toggle button named "ExpanderButton", in its template. Its expand/collapse function depends on the existence of this template part, because Silverlight doesn't support two way binding.
    • Expander exposes ExpansionStates visual state group (including Expanded and Collapsed two visual states) for users to customize its expand and collapse behavior.
    • Expander exposes ExpandDirectionStates visual state group (including ExpandDown, ExpandUp, ExpandLeft, ExpandRight) for users to customize the layout for each of the four expand direction.
    • Expander also exposes HeaderTemplate and ContentTemplate properties for users to customize its header and content part. You can find this kind of customization from Silverlight Control Toolkit Sample.

image

  • understand Expander's default template. The screen shot below shows how the default template handles the layout of the four expand directions and the behavior of expand/collapse by providing StoryBoard for the ExpansionStates and ExpandDirectionStates visual state groups:
    • The whole Header is a templated ToggleButton, so clicking anyway on the Header may expand/collapse the Content area.
    • It uses a 2x2 Grid to layout Header and Content area.
    • It lays out the Expander according to ExpandDirection by having state animation for ExpandDirectionStates:
      • It lays out Header and Content areas by animating their Grid.Row and Grid.Column properties.
      • It draws the header toggle button correctly by changing its template.
    • It expands/collapses content areas by animating its Visibility attribute in ExpanionStates state transitions.

ExpandDirection state animation

Below screen shot shows the most asked customizations. If you have Silverlight 2.0 installed and your reader supports live Silverlight application, you can play with it here too:

Expander Customization

  • PDC08 shows the Expander in current release on codeplex. There is a bug in ExpanderRightHeaderTemplate (used if you set ExpandDirection to Right) that causes high CPU and memory usage. This is fixed and the fix will be in our next release in a few weeks. I apologize for the inconvenience. Expander is my very first Silverlight control. I didn't know anything about Silverlight or WPF before I joined Shawn's team a few months back, and I still can't believe how fragile xaml and animation are. It took me a long time to track down the one character fix: one (out of dozens) ObjectAnimationKeyFrames has Duration attribute accidentally set to "1" instead of "0". That drove Silverlight runtime nuts and hog cpu/memory.
  • New (ExpanderStyle) shows the new template to be released soon.
  • Fade In/Out (ExpanderFadeStyle) customizes the expand/collapse behavior by animating Opacity to fade the content in and out.
  • Scale In/Out (ExpanderScaleStyle) customizes the expand/collapse behavior by animating ScaleTransform.ScaleX and ScaleTransform.ScaleY between 1 and 0 to expand and shrink the content.
  • No Button (ExpanderNoButtonStyle) customizes the layout by removing the circle with arrow toggle button. You can still expand/collapse content with mouse or keyboard.
  • Bottom/Right Button (ExpanderBottomRightButtonStyle) customizes the layout by putting the the circle with arrow toggle button to the bottom/right part of the header.

 

Source Code

You can find the zipped project file:

Conclusion

Expander has been the top keyword to my blog. It is a very useful control and relatively hard to customize. Hopefully this post will help you in using and customizing Expander. Thanks!

Nov 5, 2008

Expander Control in Silverlight Toolkit

Introduction

I wrote the HeaderedContentControl and Expander for Silverlight Toolkit. They both exist in WPF, and I wrote them to be as much compatible with WPF as possible. But there are significant differences between WPF and Silverlight, so not surprisingly controls on those two platforms are different as well. The differences are mostly caused by the differences of DependencyProperty system between WPF and Silverlight, and new Silverlight innovations like TemplatePart and VisualState. There have been several search referrals to my blog for keywords "Silverlight" "Expander", I thought I should write a post about the design and implementation of HeaderedContentControl and Expander, so here you go.

HeaderedContentControl

HeaderedContentControl inherits from ContentControl, adding two DependencyProperty Header and HeaderTemplate, and two protected virtual function OnHeaderedChanged and OnHeaderTemplateChanged. Below are HeaderedContentControl in Silverlight Toolkit and WPF. The differences are mostly new features added in WPF 3.5 like HeaderStringFormat and OnHeaderStringFormatChanged, and platform differences between WPF and Silverlight, like HeaderTemplateSelector, LogicalChildren, and HasHeader etc.

 HeaderedContentControl in Silverlight Toolkit

Figure 1: HeaderedContentControl in Silverlight Toolkit

HeaderedContentControl in WPF

Figure 2: HeaderedContentControl in WPF

You can check out HeaderedContentControl overview and play with samples from Silverlight Toolkit codeplex page.

Expander

User Interface

Expander is a subclass of HeaderedContentControl, adding the behavior of expanding/collapsing its Content area. The Silverlight Toolkit home page has a screen shot of a customized Expander:

Silverlight Toolkit 

Figure 3: Customized HeaderedContentControl

And samples you can play with:

image

Figure 4: HeaderedContentControl sample

Besides mouse interface (clicking header/togglebutton to expand/collapse), Expander also has a keyboard interface: depending on the ExpandDirection, left/right/down/up arrow keys may expand or collapse Expander Content area too.

Implementation

Expander adds two DependencyProperty IsExpand and ExpandDirection, two events Expanded and Collapsed, and their related protected virtual methods OnExpanded and OnCollapsed. Below are implementation of Expander in Silverlight Toolkit and WPF:

Expander in Silverlight Toolkit

Figure 5: Expander in Silverlight Toolkit

Expander in WPF

Figure 6: Expander in WPF

Control Contract & Customization

What's new in Expander in Silverlight Toolkit, relative to its WPF counterpart, is the control contract:

image

Figure 7: Expander control contract: template parts and visual states

Expander adds two new visual state groups, besides the common and focus groups:

  • ExpansionStates: Expanded & Collapsed

As shown below, the default template of Expander has state animation for Expanded and Collapsed states, using ObjectAnimationUsingKeyFrames to change the Visibility property of Content area (represented by ExpandSite element in default template), to show or hide the Content area. You can customize the expand/collapse behavior easily with Blend, like adding a transition animation to change the Opacity of Content area fade it in and out.

Expand State Animation

Figure 8: Expanded State Animation

  • ExpandDirectionStates: ExpandDown, ExpandUp, ExpandLeft & ExpandRight

Expander has four different ExpandDirection values, each has a different layout. To allow users customize Expander template, there must be a way to specify the four layout in template so Expander code knows which one to pick and what components to show/hide according to the ExpandDirection property. Controls like Slider and ScrollBar used the TemplatePart:

ScrollBar

This approach doesn't scale well: Expander has four layouts, thus lots of template parts. And each layout must handle Expanded/Collapsed transitions separately. To avoid this problem, I introduced the ExpandDirectionStates visual state group, so users can customize the layout by handling ExpandDirectionStates, which Blend provides good support for. I have to specify one template part: the header ToggleButton, because Silverlight doesn't allow two way binding, so I have to associate Expander.IsExpanded with ToggleButton.IsChecked in Expander code, to provide the expand/collapse user experience. So this way, the control contract is much cleaner and far more flexible, like it is easy to add a RotateTransform to rotate Expander to new layout when ExpandDirection changes. The screen shot below shows how the default template handles all four layout:

  • The whole Header is a templated ToggleButton, so clicking anyway on the Header may expand/collapse the Content area.
  • It uses a 2x2 Grid to layout Header and Content area.
  • It lays out the Expander according to ExpandDirection by having state animation for ExpandDirectionStates:
    • It lays out Header and Content areas by animating their Grid.Row and Grid.Column properties.
    • It draws the header toggle button correctly by changing its template.

ExpandDirection state animation

Figure 9: ExpandLeft State Animation

Conclusion

As always, hope this helps, and comments/suggestions/feedbacks etc are welcome. Thanks!