コード例 #1
0
        private void Recalculate(bool doLayout)
        {
            if (!IsHandleCreated)
            {
                return;
            }

            Size canvas = canvas_size;
            Size client = ClientSize;

            canvas.Width  += auto_scroll_margin.Width;
            canvas.Height += auto_scroll_margin.Height;

            int right_edge  = client.Width;
            int bottom_edge = client.Height;
            int prev_right_edge;
            int prev_bottom_edge;

            bool hscroll_visible;
            bool vscroll_visible;

            do
            {
                prev_right_edge  = right_edge;
                prev_bottom_edge = bottom_edge;

                if ((force_hscroll_visible || (canvas.Width > right_edge && auto_scroll)) && client.Width > 0)
                {
                    hscroll_visible = true;
                    bottom_edge     = client.Height - SystemInformation.HorizontalScrollBarHeight;
                }
                else
                {
                    hscroll_visible = false;
                    bottom_edge     = client.Height;
                }

                if ((force_vscroll_visible || (canvas.Height > bottom_edge && auto_scroll)) && client.Height > 0)
                {
                    vscroll_visible = true;
                    right_edge      = client.Width - SystemInformation.VerticalScrollBarWidth;
                }
                else
                {
                    vscroll_visible = false;
                    right_edge      = client.Width;
                }
            } while (right_edge != prev_right_edge || bottom_edge != prev_bottom_edge);

            if (right_edge < 0)
            {
                right_edge = 0;
            }
            if (bottom_edge < 0)
            {
                bottom_edge = 0;
            }

            Rectangle hscroll_bounds;
            Rectangle vscroll_bounds;

            hscroll_bounds = new Rectangle(0, client.Height - SystemInformation.HorizontalScrollBarHeight,
                                           ClientRectangle.Width, SystemInformation.HorizontalScrollBarHeight);
            vscroll_bounds = new Rectangle(client.Width - SystemInformation.VerticalScrollBarWidth, 0,
                                           SystemInformation.VerticalScrollBarWidth, ClientRectangle.Height);

            /* the ScrollWindow calls here are needed
             * because (this explanation sucks):
             *
             * when we transition from having a scrollbar to
             * not having one, we won't receive a scrollbar
             * moved (value changed) event, so we need to
             * manually scroll the canvas.
             *
             * if you can fix this without requiring the
             * ScrollWindow calls, pdb and toshok will each
             * pay you $5.
             */

            if (!vscrollbar.Visible)
            {
                vscrollbar.Value = vscrollbar.Minimum;
            }
            if (!hscrollbar.Visible)
            {
                hscrollbar.Value = hscrollbar.Minimum;
            }

            /* Manually setting the size of the thumb should be done before
             * the other assignments */
            if (hscroll_visible)
            {
                hscrollbar.manual_thumb_size = right_edge;
                hscrollbar.LargeChange       = right_edge;
                hscrollbar.SmallChange       = 5;
                hscrollbar.Maximum           = canvas.Width - 1;
            }
            else
            {
                if (hscrollbar != null && hscrollbar.VisibleInternal)
                {
                    ScrollWindow(-scroll_position.X, 0);
                }
                scroll_position.X = 0;
            }

            if (vscroll_visible)
            {
                vscrollbar.manual_thumb_size = bottom_edge;
                vscrollbar.LargeChange       = bottom_edge;
                vscrollbar.SmallChange       = 5;
                vscrollbar.Maximum           = canvas.Height - 1;
            }
            else
            {
                if (vscrollbar != null && vscrollbar.VisibleInternal)
                {
                    ScrollWindow(0, -scroll_position.Y);
                }
                scroll_position.Y = 0;
            }

            if (hscroll_visible && vscroll_visible)
            {
                hscroll_bounds.Width  -= SystemInformation.VerticalScrollBarWidth;
                vscroll_bounds.Height -= SystemInformation.HorizontalScrollBarHeight;

                sizegrip.Bounds = new Rectangle(hscroll_bounds.Right,
                                                vscroll_bounds.Bottom,
                                                SystemInformation.VerticalScrollBarWidth,
                                                SystemInformation.HorizontalScrollBarHeight);
            }

            SuspendLayout();

            hscrollbar.SetBounds(hscroll_bounds.X, hscroll_bounds.Y, hscroll_bounds.Width, hscroll_bounds.Height, BoundsSpecified.All);
            hscrollbar.Visible = hscroll_visible;
            if (hscrollbar.Visible)
            {
                XplatUI.SetZOrder(hscrollbar.Handle, IntPtr.Zero, true, false);
            }

            vscrollbar.SetBounds(vscroll_bounds.X, vscroll_bounds.Y, vscroll_bounds.Width, vscroll_bounds.Height, BoundsSpecified.All);
            vscrollbar.Visible = vscroll_visible;
            if (vscrollbar.Visible)
            {
                XplatUI.SetZOrder(vscrollbar.Handle, IntPtr.Zero, true, false);
            }

            UpdateSizeGripVisible();

            ResumeLayout(doLayout);

            // We should now scroll the active control into view,
            // the funny part is that ScrollableControl does not have
            // the concept of active control.
            ContainerControl container = this as ContainerControl;

            if (container != null && container.ActiveControl != null)
            {
                ScrollControlIntoView(container.ActiveControl);
            }
        }