【问题标题】:Programmatically Scrolling is not working C# WinForm以编程方式滚动不起作用 C# WinForm
【发布时间】:2014-09-19 23:21:44
【问题描述】:

我有一个面板,我在主面板中放置了一个流程布局面板,流程布局面板有很多图像。我的用户界面看起来像这样

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

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

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 &lt;= metroPanel1.Left &amp;&amp; e.X &gt;= metroPanel1.Left - 40)

我想我需要使用不同的值而不是 40,但我使用了 10 和 20 但没有用。 这是我的完整项目链接,任何人都可以从中下载并查看我的例程中阻止滚动的问题。这是链接https://onedrive.live.com/embed?cid=C4A6F16F34D7540A&resid=C4A6F16F34D7540A%21134&authkey=AM5Fq2gcFLtcw_A

所以我的请求是请某人查看我的代码并指导我需要更改代码的内容以及原因。谢谢

【问题讨论】:

  • 看起来 40 只是填充,让您有一个间隙来查看鼠标是否靠近边缘而不是正好在边缘,如果有的话,您最好增加这个值(在测试期间)
  • 我如何检测我应该给出什么值,比如 40 或 60....只是通过跟踪和错误?有什么捷径可以知道我应该使用什么值吗?谢谢
  • 基本上就是这样,它的大部分试验和错误,40像素对我来说听起来足够大,但它适合你
  • 我也测试了 60 和 80,但仍然没有运气。
  • 这可能不是问题所在,只需在其中一个 if 条件中设置一个断点,看看它是否被命中,如果是,会发生什么。你的问题可能太宽泛了

标签: c# winforms


【解决方案1】:

当你想滚动时不要使用

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

而是

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

变态

【讨论】:

  • 对不起我的 cmets - 是的,这确实有所作为,即使没有可见的滚动条,它也会滚动面板!我将它应用到 FLP,它根本不会以任何方式滚动..该睡觉了,明天我会看看更改鼠标滚动代码是否会让事情变得更容易.. 可能可以保存停止代码..
  • 我想请求您从这个链接onedrive.live.com/… 下载我的示例项目并进行所有必要的更改以进行滚动工作。我遵循您的代码,但仍然没有运气。谢谢
  • @Thomas 它开箱即用。它闪烁,运动有点波涛汹涌,但有效。
  • 我给你的示例链接没有完全滚动。请检查,如果可能的话,使这个应用程序完美。谢谢
  • @Thomas 抱歉,我还没有使用 Metro 框架。如果是常规控件,那么我可以这样做。
【解决方案2】:

是的。

是的,如果Scrollbars 未显示,则以编程方式滚动FlowLayoutPanel不工作,因为它的AutoScroll 已关闭。

既不设置HorizontalScroll.Value(以任何方式)也不使用

[DllImport("user32.dll")]
static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);

什么都会做。

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

flowLayoutPanel1ScrollControlIntoView(someControlThatsOutOfSight);

所以,据我所知:没有活动的滚动条就不能滚动FlowLayoutPanel

包含Panel 的内容确实可以像 valter 显示的那样滚动。然而,我的第一次测试表明,即使使用双缓冲面板子类也会出现可怕的闪烁......

更新:

我无法让面板可靠地滚动。我检查了链接,发现行为确实比我写的任何东西都简单得多:没有上下滚动,没有边缘检测,没有速度检测,没有方向检测。实际上有两个滚动区域,当鼠标在一个区域时,它会滚动.. 它还依赖于“不断触发 mousemove 事件错误”,它只在我不想要它时才对我有用..!

所以,这里有一个实现这种行为的解决方案,当然比原始代码要短得多。

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

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

代码如下:

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;
}

这几乎就是您所需要的。仅当您停靠或锚定外部面板时,您才应该编写调整大小事件以保持内部面板居中!

【讨论】:

  • 感谢您的回答。你说“我对 mouseSroller 做了一些很好的改进和更正,稍后或明天上传”所以请给我链接,我可以通过它下载你改进的滚动项目版本。谢谢
  • 嘿,在我完成我的课程之前,我开始想知道一个细节:什么时候应该开始滚动?光标必须足够近,这很清楚。但是它的运动呢?在移动的同时开始滚动是否可以? (这就是我现在所拥有的......)还是应该在光标在滚动区域中停留一会儿时开始?或者只有在运动不太快的情况下..?? - 问题是:我认为应该可以将光标移出 FLP / 表单。无需开始滚动!
  • 这里我提供了一个链接,您可以下载一个示例 Winform 项目。onedrive.live.com/… 只是开发类似的东西。但仅使用内置面板和 FLP 来开发您的 UI。链接很好......只要看到它你会很高兴。
  • 检查了代码并写了一个简单的实现..只有十几行代码;-)
  • 感谢您的回答。你能以 zip 格式上传你的源代码吗?
猜你喜欢
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多