none
[C#]winform的子窗口的panel滚动条复位的问题 RRS feed

  • 问题

  • 请教个问题,很急。
    按如下步骤建立c#的应用程序。
    1,建立三个form:form1是父窗口,form2和form3都是子窗口,并且同时显示两个子窗口。
    2,form2上有个panel,panel的autoscroll设置为true,
    panel放上一个任意控件(比如文本框),
    这样当panel的控件大于panel的大小时,就会自动出现滚动条。
    3,运行程序,先拖动form2上的滚动条,然后点击form3,再点击form2文本框,
    会出现滚动条复位的问题,请问怎么解决这个bug?
    p.s.请尽量不使用scrollbar等其他控件来替代。
    2009年11月30日 5:26

答案

  • private int verticalScroll = 0;
    private int horizontalScroll = 0;
    
    private void Form2_Load(object sender, EventArgs e)
    {
        // 窗体得到焦点时重置
        this.Activated += new EventHandler(delegate(object o, EventArgs x)
        {
            this.panel1.VerticalScroll.Value = this.verticalScroll;
            this.panel1.HorizontalScroll.Value = this.horizontalScroll;
        });
    
        // 其它控件焦点时重置
        this.richTextBox1.Enter += new EventHandler(delegate(object o, EventArgs x)
        {
            this.panel1.VerticalScroll.Value = this.verticalScroll;
            this.panel1.HorizontalScroll.Value = this.horizontalScroll;
        });
        // 失去焦点时记录
        this.Deactivate += new EventHandler(delegate(object o, EventArgs x)
        {
            this.verticalScroll = this.panel1.VerticalScroll.Value;
            this.horizontalScroll = this.panel1.HorizontalScroll.Value;
        });
    }

    知识改变命运,奋斗成就人生!
    • 已标记为答案 sinbbxxx 2009年12月1日 1:01
    2009年11月30日 6:37
    版主
  • 此问题解决了,是一个老外教的,不过还是感谢版主的帮忙,thx   lol



    http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/65bebbf3-74b3-4723-8a22-b84cb4fa8105

    you have to store the position of scroll bars in two variables and when the form is activated. Assign the position from that variables to scroll bars again.

    Check this code for Form2.

        public partial class Form2 : Form
        {
            int X_Value; // Stores position of Horizontal scroll bar
            int Y_Value; // Stores position of Vertical scroll bar
    
            public Form2()
            {
                InitializeComponent();
            }
    
            private void panel1_Scroll(object sender, ScrollEventArgs e)
            {
                if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)
                {
                    X_Value = e.NewValue;
                }
    
                if(e.ScrollOrientation == ScrollOrientation.VerticalScroll)
                {
                    Y_Value = e.NewValue;
                }
            }
    
            private void Form2_Activated(object sender, EventArgs e)
            {
                panel1.AutoScrollPosition = new Point(X_Value, Y_Value);
            }
        }
    
    • 已标记为答案 sinbbxxx 2009年12月1日 1:01
    2009年12月1日 1:01
  • 在 from2 失去焦点时记录滚动条位置。在 from2 被激活时重新设置滚动条位置
    知识改变命运,奋斗成就人生!
    • 已标记为答案 YiChun Chen 2009年12月1日 10:06
    2009年11月30日 6:09
    版主

全部回复

  • 你好!

    form2 不要用 panel 了,使用 richTextBox 滚动条也是使用 richTextBox 的滚动条。

    知识改变命运,奋斗成就人生!
    2009年11月30日 5:56
    版主
  • 你好:

    由于项目原因,必须用panel,
    里面放的不是richTextBox,
    请问有什么方法解决不?
    2009年11月30日 5:58
  • 在 from2 失去焦点时记录滚动条位置。在 from2 被激活时重新设置滚动条位置
    知识改变命运,奋斗成就人生!
    • 已标记为答案 YiChun Chen 2009年12月1日 10:06
    2009年11月30日 6:09
    版主
  • 在 from2 失去焦点时记录滚动条位置。在 from2 被激活时重新设置滚动条位置
    知识改变命运,奋斗成就人生!

    你好!
    请问是这样吗?

    激活时:
    this.panel1.AutoScrollPosition = new Point(poiPosition.X, poiPosition.Y);
    Application.DoEvents();
    离开时:
    poiPosition = this.panel1.AutoScrollPosition;


    不过我分别在Form2_Activated和Form2_Deactivate
    及Form2_Enter和Form2_Leave里增加上述处理都没有效果。。。
    2009年11月30日 6:25
  • private int verticalScroll = 0;
    private int horizontalScroll = 0;
    
    private void Form2_Load(object sender, EventArgs e)
    {
        // 窗体得到焦点时重置
        this.Activated += new EventHandler(delegate(object o, EventArgs x)
        {
            this.panel1.VerticalScroll.Value = this.verticalScroll;
            this.panel1.HorizontalScroll.Value = this.horizontalScroll;
        });
    
        // 其它控件焦点时重置
        this.richTextBox1.Enter += new EventHandler(delegate(object o, EventArgs x)
        {
            this.panel1.VerticalScroll.Value = this.verticalScroll;
            this.panel1.HorizontalScroll.Value = this.horizontalScroll;
        });
        // 失去焦点时记录
        this.Deactivate += new EventHandler(delegate(object o, EventArgs x)
        {
            this.verticalScroll = this.panel1.VerticalScroll.Value;
            this.horizontalScroll = this.panel1.HorizontalScroll.Value;
        });
    }

    知识改变命运,奋斗成就人生!
    • 已标记为答案 sinbbxxx 2009年12月1日 1:01
    2009年11月30日 6:37
    版主
  • private int verticalScroll = 0;
    
    private int horizontalScroll = 0;
    
    
    
    private void Form2_Load(object sender, EventArgs e)
    
    {
    
        // 窗体得到焦点时重置
    
        this.Activated += new EventHandler(delegate(object o, EventArgs x)
    
        {
    
            this.panel1.VerticalScroll.Value = this.verticalScroll;
    
            this.panel1.HorizontalScroll.Value = this.horizontalScroll;
    
        });
    
    
    
        // 其它控件焦点时重置
    
        this.richTextBox1.Enter += new EventHandler(delegate(object o, EventArgs x)
    
        {
    
            this.panel1.VerticalScroll.Value = this.verticalScroll;
    
            this.panel1.HorizontalScroll.Value = this.horizontalScroll;
    
        });
    
        // 失去焦点时记录
    
        this.Deactivate += new EventHandler(delegate(object o, EventArgs x)
    
        {
    
            this.verticalScroll = this.panel1.VerticalScroll.Value;
    
            this.horizontalScroll = this.panel1.HorizontalScroll.Value;
    
        });
    
    }
    
    

    知识改变命运,奋斗成就人生!


    thx  :)
    不过还横向滚动条还是会复位,可能是其他原因,我再看看,
    多谢了。。。。
    2009年11月30日 6:47
  • 你好:

    刚才的方法还是有问题:

    1,第一次激活form2时横向滚动条复位,第二次激活form2时纵向滚动条复位;
    2,切换到其他窗口再切换回来(比如切换到桌面再切换回来,全复位了);

    本人刚接触c#,对其机制了解不多,我猜是不是需要在父窗口一级或者父窗口上面一级来重置滚动条?
    谢谢!
    2009年11月30日 7:18
  • 此问题解决了,是一个老外教的,不过还是感谢版主的帮忙,thx   lol



    http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/65bebbf3-74b3-4723-8a22-b84cb4fa8105

    you have to store the position of scroll bars in two variables and when the form is activated. Assign the position from that variables to scroll bars again.

    Check this code for Form2.

        public partial class Form2 : Form
        {
            int X_Value; // Stores position of Horizontal scroll bar
            int Y_Value; // Stores position of Vertical scroll bar
    
            public Form2()
            {
                InitializeComponent();
            }
    
            private void panel1_Scroll(object sender, ScrollEventArgs e)
            {
                if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)
                {
                    X_Value = e.NewValue;
                }
    
                if(e.ScrollOrientation == ScrollOrientation.VerticalScroll)
                {
                    Y_Value = e.NewValue;
                }
            }
    
            private void Form2_Activated(object sender, EventArgs e)
            {
                panel1.AutoScrollPosition = new Point(X_Value, Y_Value);
            }
        }
    
    • 已标记为答案 sinbbxxx 2009年12月1日 1:01
    2009年12月1日 1:01
  • 不用客气呀,解决了就好!
    知识改变命运,奋斗成就人生!
    2009年12月1日 1:13
    版主
  • 学习了 多谢
    2014年2月11日 6:56