WinForm HScrollBar用法

需求:某个控件的属性

1、有最小宽度;

2、可以随着父控件宽度的增大而增大;

3、小于最小宽度时,显示滚动条;

刚开始设置Anchor属性为:Left | Top | Right | Bottom,可以满足第二个条件,但是出现不了滚动条(即使设置父控件的AutoScroll=True也不行)。

以下是用HScrollBar控件解决问题的过程,父控件是指包含实际显示控件和滚动条控件的自定义控件,子控件是实际显示的控件

1、创建用户自定义WinForm控件,将子控件包含进去,设置父控件的Anchor属性为:Left | Top | Right | Bottom,主要是为了解决以上第二个要求;

2、创建类,类中添加HScrollBar滚动条控件

    /// <summary>
    /// 主界面滚动条类
    /// </summary>
    public class MainPageHScroll
    {
        HScrollBar hScrollBar1 = new HScrollBar();
        int preScrollValue = 0;
        Panel panel;
        internal void Init(Panel panel,int hScrollMaxValue)
        {
            this.panel = panel;
            hScrollBar1.Height = 11;
            hScrollBar1.Left = 1;
            hScrollBar1.Visible = false;
            hScrollBar1.ValueChanged += HScrollBar1_ValueChanged;
            hScrollBar1.SmallChange = 5;
            hScrollBar1.Minimum = 0;
            hScrollBar1.Maximum = hScrollMaxValue;
        }
        
        private void HScrollBar1_ValueChanged(object sender, EventArgs e)
        {
            var diffValue = preScrollValue- hScrollBar1.Value;
            preScrollValue = hScrollBar1.Value;
            panel.Left += diffValue;
        }

        internal void HideHScroolBar()
        {
            hScrollBar1.Visible = false;
            //例如最大化窗口时,宽度大于指定的宽度时,所以此时要隐藏滚动条,并且设置值为0。
            //隐藏滚动条是因为宽度大于指定的宽度了,所以下次再显示滚动条时,肯定要显示在最左边,所以要设置值为0
            hScrollBar1.Value = 0;
        }
        /// <summary>
        /// 控件宽度变化时,调整滚动条的各个属性值
        /// </summary>
        /// <param name="top"></param>
        /// <param name="width"></param>
        /// <param name="largeChange"></param>
        internal void AdjustHScroolBar(int top,int width,int largeChange)
        {
            hScrollBar1.Visible = true;
            hScrollBar1.Top =  top;
            hScrollBar1.Width = width - hScrollBar1.Left;
            hScrollBar1.LargeChange = largeChange<0?0:largeChange;
            //滚动块处于滚动条的中间位置时,改变控件的宽度时,
            //1、滚动条的Value不变,但是滚动条的宽度改变了,这个通过改变LargeChange就可以实现;
            //2、当滚动块位于最右边时,再次增加控件宽度时,滚动条的位置要改变,让控件的左边显示出来,这时必须要更新Value
            //如何知道滚动块从中间滚动到最右边了呢?使用下面的条件判断:
            //1、需要滚动的所有控件的宽度加起来有一个最小宽度(正是因为有最小宽度,所以才会出现滚动条);
            //2、当显示滚动条后,并且滚动条位于最右边时,再放大panel的宽度时,那么此时largeChange肯定要大于最右边的控件的Right(因为最左边的控件的left值已经为负数了)
       //子控件的Anchor属性必须为:Left | Top,否则以下条件不生效 if (largeChange >= panel.Right) { var hValue = hScrollBar1.Maximum - largeChange - 1; hScrollBar1.Value = hValue< hScrollBar1.Minimum?hScrollBar1.Minimum:hValue; } } internal Control GetHScroll() { return hScrollBar1; } internal int GetHScrollHeight() { return hScrollBar1.Height; } }

 

3、在父控件中初始化滚动条控件

//panel1为实际需要显示信息的控件

mainPageHScroll.Init(
panel1,
panel1.Right-10//滚动条的最大值
);

this.Controls.Add(mainPageHScroll.GetHScroll());

4、在父控件中设置大小改变时间处理函数

this.Resize += ResizeHandler;
private void ResizeHandler(object sender, EventArgs e)
        {
            //1、控件的大小改变时,需要调整控件的宽度和高度,但是不调整控件的位置,位置是通过滚动条的ValueChanged事件函数调整的。
            //2、如果宽度小于指定的宽度时,显示水平滚动条,所以显示滚动条和隐藏滚动条时,要分别调整控件的高度,让滚动条显示或者
            //   隐藏。
            if(this.Width < initWidth)//如果小于指定的最小宽度
            {
               //这里插入代码可以调整父控件的高度,主要是显示滚动条后,要减去滚动条的高度
                mainPageHScroll.AdjustHScroolBar(
                    panel1.Bottom + 1,
                    this.Width - horizonInterval,
                    this.Width - 2
                    );
            }
            else
            {
                //这里插入代码可以调整父控件的宽度和高度,主要是隐藏滚动条后,要加上滚动条的高度
                mainPageHScroll.HideHScroolBar();
            }
        }

 

posted @ 2021-02-06 11:42  carrot_hlb  阅读(1644)  评论(0编辑  收藏  举报