Home > Silverlight > Expander in silverlight

Expander in silverlight

I was trying to do something like ‘Accordion’ in silverlight, but ran into issues with animating the height. I had set the ‘To ‘ value for the double animation(s) in code and still have to figure out why the rotate transform is not rotating at the center

Here is the sample updated to beta 2

Here is the sample updated to fix an issue with IsExpanded property

  1. Fallon Massey
    June 25, 2008 at 1:05 am | #1

    Lee, I can’t get this to work in Beta 2.

    Any chance you could take a look at it, and make the conversion?

    Thanks.

  2. lee
    June 25, 2008 at 3:06 am | #2

    Hi Fallon Massey,

    Added another link with the sample updated to beta2
    http://cid-71b364b59919d1e8.skydrive.live.com/self.aspx/Public/blog%20files/AnimatedExpander%20beta%202.zip

    Thanks

  3. Fallon Massey
    June 25, 2008 at 6:58 am | #3

    WOW, that was quick.

    Thanks Lee, and I love the work you’re doing here.

    Fallon.

  4. RichardJ
    June 25, 2008 at 1:34 pm | #4

    Is there a way to have the expander start in the expanded state? If I set IsExpanded to true after constructing the object (in code) then I get a Null Ref exception in the IsExpandedChanged callback.

    Thanks.

  5. lee
    June 25, 2008 at 2:12 pm | #5

    the template was not applied when it was trying to handled the callback, so modified code
    this code should allow you to set the IsExpanded property
    http://cid-71b364b59919d1e8.skydrive.live.com/self.aspx/Public/blog%20files/AnimatedExpander%7C52%7C6.zip

  6. Fallon Massey
    June 29, 2008 at 6:58 am | #6

    Lee, where do I change the duration of the animation? In the generic.xaml, or somewhere else?

  7. lee
    June 29, 2008 at 7:43 am | #7

    Fallon,
    you should change in generic.xaml, only the height is changed in code

  8. Fallon Massey
    June 30, 2008 at 12:28 am | #8

    Lee, a couple of items.

    1. On your updated sample, after you close the first level, it loses, or possibly never had it’s ScrollableHeight set. Therefore, it is never able to open again, except to the 10 pixels you add on in code.

    2. I tried to make the expander open up faster, but no luck. No matter what I change the duration to, it still goes at the same rate… help.

  9. lee
    June 30, 2008 at 9:05 am | #9

    Fallon,
    try the updated version http://cid-71b364b59919d1e8.skydrive.live.com/self.aspx/Public/blog%20files/Accordion%20updated.zip, changed how it is used, see page.xaml for sample
    2. I faced the same issue when I initially wrote it couple of months back, anything below 1sec doesnt work. No Idea

    Thanks

  10. Fallon Massey
    July 1, 2008 at 6:37 am | #10

    Thanks Lee.

    If I figure out #2, I’ll let you know.

  11. lee
    July 1, 2008 at 8:25 am | #11

    Thanks Fallon

  12. RichardJ
    July 1, 2008 at 8:45 am | #12

    In your latest code, I think the +10 in IsExpandedChanged only needs to be applied to the ScrollableHeight, not to the border.ActualHeight. I seemed to be getting a double spacing on the second and subsequent expands.

  13. lee
    July 1, 2008 at 12:21 pm | #13

    Richard,
    I am not seeing the same thing as you are. I know I have changed the sample few times. are you looking at the same .zip file as in comment#9. that is the latest of what I have

    Thanks
    lee

  14. RichardJ
    July 2, 2008 at 8:14 am | #14

    Yes, I’m pretty sure I have the same code for those few lines. I think the difference is that I create my expanders and have them in the expanded state, perhaps this is why you are not seeing it?

    Regards,
    Richard

  15. Bob Leonard
    July 2, 2008 at 5:27 pm | #15

    Lee,

    Very nice work. I am having an issue however you may be able to help me with. I dynamically change the number of items in the expansion area by changing the ItemsSource at runtime. When I do so to an set that has been expanded at any point the expansion area does not expand to the correct size if re-expanded. So if the original expansion had 5 items on re-expansion only 5 items will show. Any ideas on where this should be addressed ?

    Thanks,
    Bob

  16. lee
    July 2, 2008 at 6:09 pm | #16

    Bob,
    In the code I believe, the height of the border is set after the initial load and is not reacting to future changes of number of Items(ItemsSource). Let me take a look and will see if that can take into ItemSource changes

    Thanks

  17. lee
    July 2, 2008 at 6:31 pm | #17

    Bob,
    quick fix – Adding the following in HeaderedItemsControl.cs file, should make it size accordingly.

    (note: this will not work if the Item is expanded when you are changing the Itemssource)

    protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
    base.OnItemsChanged(e);
    ChangedStoryboard = false;
    }

  18. Jon
    July 28, 2008 at 11:11 pm | #18

    8) #2 To fix the duration problem, in the generic.xaml file move the “Duration” lines from the Storyboard to the DoubleAnimation line.

  19. lee
    July 29, 2008 at 12:51 pm | #19

    jon,
    Thanks for the hint

  20. Alek
    September 12, 2008 at 6:03 pm | #20

    i can’t get this to open in a browser.
    i can’t get this to open in visual studio.
    i can’t get this to open in Blend 2.

    it doesn’t support SlControls ?

    Any hint’s for us dreamweaver coders?

  21. lee
    September 12, 2008 at 7:26 pm | #21

    did you download the zip file?

  22. Connie
    November 2, 2008 at 3:49 am | #22

    Hi Lee,

    I have tried your accordion control with the newly released Silverlight 2. I keep having this Null reference problem. It was in HeaderedItemsControl.cs, during OnApplyTemplate(), _header was null. Any hint on how to fix this in Silverlight 2? I love to have this accordion control shown on my web app.

    Thanks,
    Connie

  23. lee
    November 2, 2008 at 10:43 am | #23

    Connie,
    Create a folder called “Themes” in your project and move the “generic.xaml” file into that.
    that should fix it

  24. edu
    January 28, 2009 at 12:35 am | #24

    Lee,

    How do I “nest” these babies?

    • lee
      January 28, 2009 at 1:05 am | #25

      Hi,
      do you want expander as one of the items?. Let me know your scenario

  25. edu
    January 28, 2009 at 8:03 am | #26

    Hi,

    Yes, the nested item is also expander.

    Am having problem. On load last item is open right? After closing it, it does not open again.

    Edu

  26. edu
    January 28, 2009 at 8:28 am | #27

    sorry for such a vague question on nesting but yes I want to add a nested expander.

    So I go

    but this causes error when it prepares each item..

    foreach (HeaderedItemsControl hec in this.Items)
    {
    hec.IsExpanded = false;
    }

    because it encounters an item which is not an hec.

    //edu

    • lee
      January 28, 2009 at 11:31 am | #28

      could you send me a sample project

  27. edu
    February 6, 2009 at 12:54 pm | #29

    Hi lee,

    Sorry it took me so long. The code I posted was from the sample project I downloaded from here. I was playing around and wondered how to nest this control. So, from your project, I edit the xaml to be like this:

  28. lee
    February 6, 2009 at 4:14 pm | #30

    I dont see any xaml

  29. edu
    February 12, 2009 at 10:59 pm | #31

    oops.. my bad

  30. edu
    February 12, 2009 at 11:02 pm | #32

    the xaml does not seem to want to be posted..

    {

    }

  31. LoveIt
    March 3, 2009 at 3:07 pm | #33

    Hi
    is it possible to start the control with one of the HeaderedItemsControl expanded?
    Now I have to start the application and expand e.g fist item by using Acordian.SelectedIndex=0. this works and is ok, but I dont want the animation effect the first time I start my application.
    Can this be done?
    tnx

    • lee
      March 3, 2009 at 3:48 pm | #34

      Hi,
      In the function (headeredItemscontrol.cs)
      void ip_Loaded(object sender, RoutedEventArgs e)
      {
      if (IsExpanded)
      {
      border.Height = (border.Child as ScrollViewer).ScrollableHeight + 10;
      //ChangeVisualState();<– comment this line }
      }

      and modify the following function to look like this

      private static void IsExpandedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
      HeaderedItemsControl h = (d as HeaderedItemsControl);
      if (h.Template != null && h.border != null)
      {
      //if (!h.ChangedStoryboard)
      //{
      ScrollViewer sv = h.border.Child as ScrollViewer;
      double height = h.border.ActualHeight;
      (h.ExpandState.Children[0] as DoubleAnimation).To = (sv.ScrollableHeight== 0? height : sv.ScrollableHeight) + 10.0;
      //h.ChangedStoryboard = true;
      //}

      h.ChangeVisualState();
      }
      }

  32. LoveIt
    March 4, 2009 at 10:39 am | #35

    excellent :) thanks alot

  33. LoveIt
    March 4, 2009 at 12:26 pm | #36

    Is it possible to create a mouse over effect as well? So that when a user holds the mouse over a item this changes color?

    • lee
      March 4, 2009 at 3:46 pm | #37

      All you have to do is to add a event handler for mouse events and begin a storyboard . or it is better to use VSM

  34. LoveIt
    March 7, 2009 at 10:11 am | #38

    Hmm Tried this but cant get it to work. Could you plz help me a bit on the way

    • lee
      March 7, 2009 at 10:35 am | #39

      sure, but will be couple of days before I can. when the mouse is over the header, you wan to change(animate) the color right?

  35. LoveIt
    March 7, 2009 at 10:11 pm | #40

    Yes this is what I want :)
    Thanks alot

  36. lee
  37. LoveIt
    March 10, 2009 at 4:18 pm | #42

    Thanks alot man :)

  38. thest
    March 17, 2009 at 3:06 pm | #43

    How can I remove the animation on the accordion? I just want them to open/close quick. I have tried setting the duration to 0 without luck
    hope you can help

    • lee
      March 17, 2009 at 3:18 pm | #44

      change the IsExpandedChanged method to look like this
      private static void IsExpandedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
      HeaderedItemsControl h = (d as HeaderedItemsControl);
      if (h.Template != null && h.border != null)
      {
      //if (!h.ChangedStoryboard)
      //{
      ScrollViewer sv = h.border.Child as ScrollViewer;
      double height = h.border.ActualHeight;
      if (h.IsExpanded)
      h.border.Height = sv.ScrollableHeight;
      else
      h.border.Height = 0;
      //(h.ExpandState.Children[0] as DoubleAnimation).To =
      //h.ChangedStoryboard = true;
      //}

      //h.ChangeVisualState();
      }
      }

  39. John
    June 3, 2009 at 7:53 am | #45

    Hi
    Thanks for this cool control.
    I just wonder about one thing. I do everything in codebehind and want to change the
    headeritemcontrol.Header = “Header”;
    and add a person object insted.
    This because I want the header to display
    e.g
    (image) John Nelson ENG

    Do you understand what I mean? Is this possible?

  40. John
    June 8, 2009 at 9:53 am | #47

    Excellent. This is what I needed.
    But I have one other issue. I do not display a list in the content, but more info about the customer.
    So I want to have
    A)(img) Name Age
    —————
    B) Birth: …
    Natinality: ..

    for each item. Now the way you do it I can dynamically change the A part but not the B part.
    Is there I way I can make both dynamically?
    Now I have just written the code in the generic class witch is not good if I want to use it other places.

  1. No trackbacks yet.