Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. WPF
  4. How do you vertically center an Expander within a ScrollViewer when it expands? [SOLVED]

How do you vertically center an Expander within a ScrollViewer when it expands? [SOLVED]

Scheduled Pinned Locked Moved WPF
helpquestion
8 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    fjparisIII
    wrote on last edited by
    #1

    I'm using the Silverlight 4 Tookit Expander all over the place. They are all contained within a ScrollViewer. Sometimes when I expand one of the Expander elements, the Expander.Header winds up above the top of the ScrollViewer and hence is not visible and so you can't see the title of the content that has been expanded. What I would like to do is center the Expander header vertically within the ScrollViewer viewport when I expand the Expander. To do this I have to set the ScrollViewer.VerticalOffset to the right value that will center the Expander in the ScrollViewer viewport. So I think I understand the problem that needs to be solved. But I haven't found a solution. Hopefully it's simple and I'm just overlooking something. The only ScrollViewer properties I've found that might be relevant to this problem are the following: ViewportHeight, VerticalOffset, ExtentHeight, and ActualHeight. I also have the mouse cursor Point relative to the Expander when the Expanded event takes place. But even with all this information, I don't seem to have the right information to compute what the VerticalOffset of the ScrollViewer should be. SOLUTION: Chalk up my inability to solve this to plain and simple User Brain Damage. The solution was SMOP: a Small Matter Of Programming. Most of the properties I identified above are not needed, only the following: VerticalOffset, ViewportHeight, and the Y coordinate of the mouse cursor position. Oh, yes! You have to perform the computation in the right event: Expander.SizeChanged, not Expander.Expanded. Only perform the offset if Expander.IsExpanded is true. So the code in my SizeChanged event looks like this:

    private void expander_SizeChanged(object sender, SizeChangedEventArgs e)
    {
    Expander expander = sender as Expander;
    if (expander != null && expander.IsExpanded)
    {
    double viewportHeight = scrollViewer.ViewportHeight;
    double verticalOffset = scrollViewer.VerticalOffset;
    double mouseVerticalOffset = MouseCursorPosition.Y;
    double newVerticalOffset =
    verticalOffset - viewportHeight / 2 + mouseVerticalOffset;
    scrollViewer.ScrollToVerticalOffset(newVerticalOffset);
    }
    }

    FYI, MouseCursorPosition is one of my properties, set in my ScrollViewer's MouseMove event. Seems

    F A 2 Replies Last reply
    0
    • F fjparisIII

      I'm using the Silverlight 4 Tookit Expander all over the place. They are all contained within a ScrollViewer. Sometimes when I expand one of the Expander elements, the Expander.Header winds up above the top of the ScrollViewer and hence is not visible and so you can't see the title of the content that has been expanded. What I would like to do is center the Expander header vertically within the ScrollViewer viewport when I expand the Expander. To do this I have to set the ScrollViewer.VerticalOffset to the right value that will center the Expander in the ScrollViewer viewport. So I think I understand the problem that needs to be solved. But I haven't found a solution. Hopefully it's simple and I'm just overlooking something. The only ScrollViewer properties I've found that might be relevant to this problem are the following: ViewportHeight, VerticalOffset, ExtentHeight, and ActualHeight. I also have the mouse cursor Point relative to the Expander when the Expanded event takes place. But even with all this information, I don't seem to have the right information to compute what the VerticalOffset of the ScrollViewer should be. SOLUTION: Chalk up my inability to solve this to plain and simple User Brain Damage. The solution was SMOP: a Small Matter Of Programming. Most of the properties I identified above are not needed, only the following: VerticalOffset, ViewportHeight, and the Y coordinate of the mouse cursor position. Oh, yes! You have to perform the computation in the right event: Expander.SizeChanged, not Expander.Expanded. Only perform the offset if Expander.IsExpanded is true. So the code in my SizeChanged event looks like this:

      private void expander_SizeChanged(object sender, SizeChangedEventArgs e)
      {
      Expander expander = sender as Expander;
      if (expander != null && expander.IsExpanded)
      {
      double viewportHeight = scrollViewer.ViewportHeight;
      double verticalOffset = scrollViewer.VerticalOffset;
      double mouseVerticalOffset = MouseCursorPosition.Y;
      double newVerticalOffset =
      verticalOffset - viewportHeight / 2 + mouseVerticalOffset;
      scrollViewer.ScrollToVerticalOffset(newVerticalOffset);
      }
      }

      FYI, MouseCursorPosition is one of my properties, set in my ScrollViewer's MouseMove event. Seems

      F Offline
      F Offline
      fjparisIII
      wrote on last edited by
      #2

      fjparisIII wrote:

      Only perform the offset if Expander.IsExpanded is true.

      Actually I like it better if you center the Expander whether or not it is expanded. Now all I have to do is animate the centering so that it doesn't jump to the middle so violently.

      F 1 Reply Last reply
      0
      • F fjparisIII

        fjparisIII wrote:

        Only perform the offset if Expander.IsExpanded is true.

        Actually I like it better if you center the Expander whether or not it is expanded. Now all I have to do is animate the centering so that it doesn't jump to the middle so violently.

        F Offline
        F Offline
        fjparisIII
        wrote on last edited by
        #3

        fjparisIII wrote:

        Now all I have to do is animate the centering so that it doesn't jump to the middle so violently.

        Impossible, at least by using a Storyboard. The only thing you can animate with a Storyboard is a Dependency Property and the ScrollViewer's VerticalOffset property is read-only. Major bummer. Why did they do that??? Googled around a bit and I found two workarounds. First you can write a ScrollViewer extension adding a dependency property implemented using ScrollViewer.ScrollToVerticalOffset(). Second, you can bite the bullet and do it the old-fashioned way: use a DispatcherTimer, which itself would call ScrollToVerticalOffset().

        1 Reply Last reply
        0
        • F fjparisIII

          I'm using the Silverlight 4 Tookit Expander all over the place. They are all contained within a ScrollViewer. Sometimes when I expand one of the Expander elements, the Expander.Header winds up above the top of the ScrollViewer and hence is not visible and so you can't see the title of the content that has been expanded. What I would like to do is center the Expander header vertically within the ScrollViewer viewport when I expand the Expander. To do this I have to set the ScrollViewer.VerticalOffset to the right value that will center the Expander in the ScrollViewer viewport. So I think I understand the problem that needs to be solved. But I haven't found a solution. Hopefully it's simple and I'm just overlooking something. The only ScrollViewer properties I've found that might be relevant to this problem are the following: ViewportHeight, VerticalOffset, ExtentHeight, and ActualHeight. I also have the mouse cursor Point relative to the Expander when the Expanded event takes place. But even with all this information, I don't seem to have the right information to compute what the VerticalOffset of the ScrollViewer should be. SOLUTION: Chalk up my inability to solve this to plain and simple User Brain Damage. The solution was SMOP: a Small Matter Of Programming. Most of the properties I identified above are not needed, only the following: VerticalOffset, ViewportHeight, and the Y coordinate of the mouse cursor position. Oh, yes! You have to perform the computation in the right event: Expander.SizeChanged, not Expander.Expanded. Only perform the offset if Expander.IsExpanded is true. So the code in my SizeChanged event looks like this:

          private void expander_SizeChanged(object sender, SizeChangedEventArgs e)
          {
          Expander expander = sender as Expander;
          if (expander != null && expander.IsExpanded)
          {
          double viewportHeight = scrollViewer.ViewportHeight;
          double verticalOffset = scrollViewer.VerticalOffset;
          double mouseVerticalOffset = MouseCursorPosition.Y;
          double newVerticalOffset =
          verticalOffset - viewportHeight / 2 + mouseVerticalOffset;
          scrollViewer.ScrollToVerticalOffset(newVerticalOffset);
          }
          }

          FYI, MouseCursorPosition is one of my properties, set in my ScrollViewer's MouseMove event. Seems

          A Offline
          A Offline
          Abhinav S
          wrote on last edited by
          #4

          Did you try setting the VerticalContentAlignment and the VerticalAlignment to stretch for the expander and for the scrollviewer?

          My signature "sucks" today

          F 1 Reply Last reply
          0
          • A Abhinav S

            Did you try setting the VerticalContentAlignment and the VerticalAlignment to stretch for the expander and for the scrollviewer?

            My signature "sucks" today

            F Offline
            F Offline
            fjparisIII
            wrote on last edited by
            #5

            Abhinav S wrote:

            Did you try setting the VerticalContentAlignment and the VerticalAlignment to stretch for the expander and for the scrollviewer?

            No. What's that supposed to accomplish? The solution I posted works perfectly fine. Besides, I've moved beyond that now and am working on animating the scroll to the center of the viewport, using a DispatcherTimer. I've got it working beautifully, but I had to set the timer interval to 1/120 of a second to get a smooth scroll. 1/60 of a second for some reason produces a jerky scroll. I've been experimenting with the duration. So far I like a duration of 0.2 seconds, producing 24 intervals. Each interval scrolls 15 vertical pixels within a viewport of 860 pixels (i.e. scrolling a little less than 430 pixels when the Expander is at the top of the viewport). Eminently smooth. Anyhow, this animation stuff is far more interesting than centering the Expander, which as far as I'm concerned I solved to my satisfaction hours ago. I'll show my animation code when I've sufficiently polished it. I've created a class to perform the animation, because I have about 100 Expander elements in 12 different classes, so I need to be clean about this.

            A 1 Reply Last reply
            0
            • F fjparisIII

              Abhinav S wrote:

              Did you try setting the VerticalContentAlignment and the VerticalAlignment to stretch for the expander and for the scrollviewer?

              No. What's that supposed to accomplish? The solution I posted works perfectly fine. Besides, I've moved beyond that now and am working on animating the scroll to the center of the viewport, using a DispatcherTimer. I've got it working beautifully, but I had to set the timer interval to 1/120 of a second to get a smooth scroll. 1/60 of a second for some reason produces a jerky scroll. I've been experimenting with the duration. So far I like a duration of 0.2 seconds, producing 24 intervals. Each interval scrolls 15 vertical pixels within a viewport of 860 pixels (i.e. scrolling a little less than 430 pixels when the Expander is at the top of the viewport). Eminently smooth. Anyhow, this animation stuff is far more interesting than centering the Expander, which as far as I'm concerned I solved to my satisfaction hours ago. I'll show my animation code when I've sufficiently polished it. I've created a class to perform the animation, because I have about 100 Expander elements in 12 different classes, so I need to be clean about this.

              A Offline
              A Offline
              Abhinav S
              wrote on last edited by
              #6

              fjparisIII wrote:

              VerticalContentAlignment and the VerticalAlignment to stretch

              These are supposed to place a control within another control. I would suggest you have a look at the documentation (for them) on msdn. And you would need to set the properties to "center" and not "stretch" as I mentioned above. I'm glad that you have managed to get this working using a workaround though.

              My signature "sucks" today

              F 1 Reply Last reply
              0
              • A Abhinav S

                fjparisIII wrote:

                VerticalContentAlignment and the VerticalAlignment to stretch

                These are supposed to place a control within another control. I would suggest you have a look at the documentation (for them) on msdn. And you would need to set the properties to "center" and not "stretch" as I mentioned above. I'm glad that you have managed to get this working using a workaround though.

                My signature "sucks" today

                F Offline
                F Offline
                fjparisIII
                wrote on last edited by
                #7

                Abhinav S wrote:

                These are supposed to...

                etc. I know what they both do. I use them all the time, both in Silverlight and WPF. I just don't see their relevance to the problem I was trying to solve.

                Abhinav S wrote:

                I'm glad that you have managed to get this working using a workaround though.

                You're talking about the centering of the Expanders, correct? I'd hardly call my solution a "workaround." It's a straightforward solution, direct and to the point. Maybe I didn't explain carefully enough what I'm trying to do. I have extensive product documentation on my Website. I have a product overview, ten tutorials, plus an "Easter egg" that gives background on how such a product ever came to be developed. Each document is initially presented as a list of Expanders within a ScrollViewer. The average list has about 8 Expanders and each Expander expands and collapses on average 8 lines of wrapping text per paragraph and maybe 5 or 6 paragraphs. The problem was to vertically center an Expander header when the user clicks on it. However, doing that was just a matter of SMOP, nothing esoteric about it at all, and I shouldn't even have asked the question to begin with. But then I immediately saw that the expansion/collapse took place so fast that it was disconcerting and that it needed to be animated. That's really the interesting part of this entire discussion, and I'm still working on it to capture all the end cases. Should have it all worked out sometime this morning, and then I'll present it under Tips and Tricks. Anyhow, I don't see how VerticalContentAlignment would play a role in this, since I don't want to keep the content vertically aligned, but only vertically aligned when the user clicks on the Expander header, and only the header for that one Expander, not all of them.

                F 1 Reply Last reply
                0
                • F fjparisIII

                  Abhinav S wrote:

                  These are supposed to...

                  etc. I know what they both do. I use them all the time, both in Silverlight and WPF. I just don't see their relevance to the problem I was trying to solve.

                  Abhinav S wrote:

                  I'm glad that you have managed to get this working using a workaround though.

                  You're talking about the centering of the Expanders, correct? I'd hardly call my solution a "workaround." It's a straightforward solution, direct and to the point. Maybe I didn't explain carefully enough what I'm trying to do. I have extensive product documentation on my Website. I have a product overview, ten tutorials, plus an "Easter egg" that gives background on how such a product ever came to be developed. Each document is initially presented as a list of Expanders within a ScrollViewer. The average list has about 8 Expanders and each Expander expands and collapses on average 8 lines of wrapping text per paragraph and maybe 5 or 6 paragraphs. The problem was to vertically center an Expander header when the user clicks on it. However, doing that was just a matter of SMOP, nothing esoteric about it at all, and I shouldn't even have asked the question to begin with. But then I immediately saw that the expansion/collapse took place so fast that it was disconcerting and that it needed to be animated. That's really the interesting part of this entire discussion, and I'm still working on it to capture all the end cases. Should have it all worked out sometime this morning, and then I'll present it under Tips and Tricks. Anyhow, I don't see how VerticalContentAlignment would play a role in this, since I don't want to keep the content vertically aligned, but only vertically aligned when the user clicks on the Expander header, and only the header for that one Expander, not all of them.

                  F Offline
                  F Offline
                  fjparisIII
                  wrote on last edited by
                  #8

                  fjparisIII wrote:

                  Should have it all worked out sometime this morning, and then I'll present it under Tips and Tricks.

                  Here is the link: http://www.codeproject.com/Tips/85359/How-to-animate-vertical-centering-of-a-Silverlight.aspx[^]

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups