Approved
Last Updated: 15 Aug 2017 09:36 by ADMIN
ADMIN
Ivan Todorov
Created on: 20 Dec 2012 07:07
Category: Panorama
Type: Feature Request
6
ADD. RadPanorama - add vertical scrolling
This will allow the users to scroll through the tiles in all rows when the available height is insufficient.

WORKAROUND:
 class CustomPanorama : RadPanorama
    {
        RadScrollBarElement vScroll;

        protected override void CreateChildItems(Telerik.WinControls.RadElement parent)
        {
            base.CreateChildItems(parent);

            this.vScroll = new RadScrollBarElement();
            this.vScroll.ScrollType = ScrollType.Vertical;
            this.vScroll.StretchHorizontally = false;
            this.vScroll.StretchVertically = true;
            this.vScroll.MinSize = new System.Drawing.Size(16, 0);
            this.vScroll.Alignment = System.Drawing.ContentAlignment.TopRight;

            this.PanoramaElement.Children.Add(vScroll);

            this.vScroll.ValueChanged += new EventHandler(vScroll_ValueChanged);
            this.PanoramaElement.GroupLayout.RadPropertyChanged += new Telerik.WinControls.RadPropertyChangedEventHandler(GroupLayout_RadPropertyChanged);
            this.PanoramaElement.TileLayout.RadPropertyChanged += new Telerik.WinControls.RadPropertyChangedEventHandler(GroupLayout_RadPropertyChanged);

            this.ScrollBarAlignment = HorizontalScrollAlignment.Bottom;
        }

        void GroupLayout_RadPropertyChanged(object sender, Telerik.WinControls.RadPropertyChangedEventArgs e)
        {
            if (e.Property == RadElement.BoundsProperty && sender == this.GetCurrentLayout())
            {
                UpdateVScroll();
            }
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            UpdateVScroll();
        }

        private void UpdateVScroll()
        {
            vScroll.Maximum = this.GetCurrentLayout().Size.Height;
            vScroll.LargeChange = Math.Max(0, (int)(this.Size.Height - this.PanoramaElement.ScrollBar.Size.Height));

            if (vScroll.LargeChange >= vScroll.Maximum)
            {
                vScroll.Visibility = ElementVisibility.Hidden;
            }
            else
            {
                vScroll.Visibility = ElementVisibility.Visible;
            }

            if (this.PanoramaElement.ScrollBar.Visibility == ElementVisibility.Visible)
            {
                vScroll.Margin = new System.Windows.Forms.Padding(0, 0, 0, this.PanoramaElement.ScrollBar.Size.Height);
            }
            else
            {
                vScroll.Margin = new System.Windows.Forms.Padding(0);
            }
        }

        void vScroll_ValueChanged(object sender, EventArgs e)
        {
            this.GetCurrentLayout().PositionOffset = new System.Drawing.SizeF(0, -this.vScroll.Value);
        }

        private LayoutPanel GetCurrentLayout()
        {
            if (this.ShowGroups)
            {
                return this.PanoramaElement.GroupLayout;
            }

            return this.PanoramaElement.TileLayout;
        }

        public override string ThemeClassName
        {
            get
            {
                return typeof(RadPanorama).FullName;
            }
            set
            {
                base.ThemeClassName = value;
            }
        }
    }
2 comments
ADMIN
Hristo
Posted on: 08 Mar 2017 12:05
Hello Xavier,

Thank you for you input.

The provided snippet appears correct and since it fits your local setup you can go ahead with it. Thank you for sharing it with the community.

Regards,
Hristo
Xavier
Posted on: 07 Mar 2017 11:44
Thanks for this useful workaround, however I've a few changes to suggest.
In my case the vertical scroll stay behind tiles, but adding the following line in CreateChildItems method should fix this :

this.vScroll.ZIndex = 1000;

Plus, in some cases, when I resize the form where the CustomPanorama is located, an infinite loop occurs with UpdateVScroll in GroupLayout_RadPropertyChanged. To fix it I added this piece of code :

int loopCount;

        void GroupLayout_RadPropertyChanged(object sender, Telerik.WinControls.RadPropertyChangedEventArgs e)
        {
            if (e.Property == RadElement.BoundsProperty && sender == this.GetCurrentLayout() && loopCount < 8)
            {
                UpdateVScroll();
                loopCount++;
            }
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            loopCount = 0;
            base.OnSizeChanged(e);
            UpdateVScroll();
        }

Setting the loopCount limit to 8 is not totally arbitrary, in my case i found that it's the number of event raise when initializing a RadPanorama. And when I block that, vScroll stay visible even when it shouldn't.
There's probably a better way to do this, but I don't have the time to look closer :/