以编程方式滚动不起作用C#WinForm

时间:2014-09-18 14:00:45

标签: c# winforms

我有一个面板,我在主面板中放置了流动布局面板,流程布局面板有许多图像。我的UI看起来像这样 enter image description here

现在我得到了一个在面板中滚动容器的代码。我的意思是当我将鼠标放在主面板的左侧或最右侧区域时,流动布局将在主面板中滚动。他们的代码工作我检查但是当我将他们的代码放在我的项目中然后这不起作用,我的意思是当我将鼠标放在主面板的左侧或最右侧区域时滚动不起作用。

这里我附上主要代码,导致在主面板中滚动流程布局面板

protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED
                return cp;
            }
        } 
         int _myval = 5;
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (e.Y < metroPanel1.Top || e.Y > metroPanel1.Top + metroPanel1.Height) return;

            if (e.X <= metroPanel1.Left && e.X >= metroPanel1.Left - 40)
            {
                if (metroPanel1.HorizontalScroll.Value <= _myval)
                {
                    metroPanel1.HorizontalScroll.Value = _myval;
                }
                else
                {
                    metroPanel1.HorizontalScroll.Value -= _myval;
                }
            }

            if (e.X <= (metroPanel1.Left + metroPanel1.Width + 40)   && e.X >= (metroPanel1.Left + metroPanel1.Width))
            {
                metroPanel1.HorizontalScroll.Value += _myval;
            }
        }

我只是不明白这里使用的值40 if (e.X <= metroPanel1.Left && e.X >= metroPanel1.Left - 40)

我想我需要使用不同的值而不是40但我使用了10&amp; 20但没有奏效。 这是我的完整项目链接,任何人都可以下载,看看我的例程中有什么错误阻止滚动。这是一个链接 https://onedrive.live.com/embed?cid=C4A6F16F34D7540A&resid=C4A6F16F34D7540A%21134&authkey=AM5Fq2gcFLtcw_A

所以我的请求是请一些人看到我的代码并指导我需要更改代码和原因。感谢

2 个答案:

答案 0 :(得分:3)

当你想要滚动时不要使用

metroPanel1.HorizontalScroll.Value -= _myval;
or
metroPanel1.HorizontalScroll.Value += _myval;

但是

_myval -= 5;
or _myval += 5;
metroPanel1.HorizontalScroll.Value = _myval;
metroPanel1.Refresh();

瓦尔特

答案 1 :(得分:1)

是的,如果由于FlowLayoutPanel关闭Scrollbars未显示AutoScroll,则以编程方式滚动HorizontalScroll.Value 无效

既不设置[DllImport("user32.dll")] static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw); (以任何方式)也不使用

flowLayoutPanel1ScrollControlIntoView(someControlThatsOutOfSight);

会做任何事情。

即使这样做也没有任何效果:

FlowLayoutPanel

所以,据我所知:没有活动的滚动条没有滚动Panel

然而,包含int speed = 10; int delta = 0; private void panOuter_MouseMove(object sender, MouseEventArgs e) { delta = e.X < panOuter.Width / 2 ? speed : -speed; scrollTimer.Start(); } private void panOuter_MouseLeave(object sender, EventArgs e) { scrollTimer.Stop(); } private void scrollTimer_Tick(object sender, EventArgs e) { int newLeft = FLP.Left + delta; int alpha = panInner.ClientRectangle.Width - FLP.ClientRectangle.Width; if (newLeft > 0) { newLeft = 0; scrollTimer.Stop(); } else if ( newLeft < alpha) { newLeft = alpha; scrollTimer.Stop(); } FLP.Left = newLeft; } 的确可以按照valter显示的方式滚动。然而,我的第一次测试显示,即使使用双缓冲Panel子类也有可怕的闪烁......

<强>更新

我无法让Panel可靠地滚动。我检查了链接,发现行为真的比我写的任何东西都简单得多:没有向上滚动,没有边缘检测,没有速度检测,没有方向检测。事实上,有两个滚动区域,当鼠标在一个滚动区域时,它会滚动...它还依赖于鼠标移动事件错误的持续触发,这对我来说只适用于我。我想要它..!

因此,这是一个实现此行为的解决方案,当然比原始代码短得多。

我包含一个屏幕截图,向您展示布局:您需要两个面板和FlowLayoutPanel。 外面板稍微宽一些,因此它的左右部分可用作滚动区域。 内部面板包含FLP; FLP的AutoSize = true。

有一个计时器scrollTimer,快速Intervall为5-10ms。

layout

以下是代码:

{{1}}

几乎所有你需要的东西。只有在您停靠或锚定外部面板的情况下,您应编写Resize事件的脚本以保持内部面板居中!