我如何制作一个在滚动条到达底部时将停止的循环 [英] How do i make a loop that will stop when a scrollbar reaches the bottom

查看:97
本文介绍了我如何制作一个在滚动条到达底部时将停止的循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好.在我的应用程序中,我需要自动滚动.不是插入符号,而是从上到下滚动以达到平滑效果.从下到上相同.我将忽略所有实际上可以使下面的功能正常工作的东西.

Hello. In my application, i need to automatically scroll. not to caret, but to scroll from the top to the bottom in a smooth effect. same with bottom to top. I will leave all of the complicated stuff out that actually lets the function below work.

private void scrolldown_Click(object sender, EventArgs e)
        {
            t.Enabled = false;
            if (t.Enabled == false)
            {
                t.Enabled = true;
            }
            else t.Enabled = true;
            while (t.Enabled == true)
            {
                scroll(telep.Handle, (speedslider.Value * 2));
            }
        }




scroll(telep.Handle, (speedslider.Value * 2));需要循环.我已经尝试过while(true),但这会使应用程序无限次执行此操作.没关系但是当滚动条到达文本框的最底部时,该应用将变得无响应.所以.我正在尝试做的是在滚动条到达最底部时停止循环.现在,我要向您显示的只是导致以上代码正常工作的部分代码.




scroll(telep.Handle, (speedslider.Value * 2)); needs to be looped. i have tried while(true) but this causes the application do this infinitely many times. this is okay. but when the scroll bar reaches the very bottom of the text box, the app becomes unresponsive. so. what i am trying to do is stop the loop when the scrollbar reaches the very bottom. now, what im about to show you is only PART of the code that causes the above to work.

// Increase posion by pixles
                if (si.nPos < (si.nMax - si.nPage))
                    si.nPos += pixels; //<-- the + can be changed to - for up movement instead of down. si is the SCROLLBARINFO and nPos is its position.
                else
                {
                    ptrWparam = new IntPtr(SB_ENDSCROLL);
                    t.Enabled = false;
                    SendMessage(handle, WM_VSCROLL, ptrWparam, ptrLparam);
                }

推荐答案

除了SA的响应外,您不应在主线程中进行循环.那将冻结您的UI.您需要在后台线程中执行类似的任务,以便您的主UI保持响应状态.您可以为此使用BackgroundWorker (在MSDN上查找).
In addition to SA''s response, you should not do a loop in your main thread. That will freeze up your UI. You need to do tasks like this in a background thread so your main UI will remain responsive. You can use BackgroundWorker for this (look it up on MSDN).


这些年来,我们进行了许多控制,我一直发现最好,最流畅的是滚动条操作的一种方法是仅移动已绘制的内容-如果您已经绘制的任何内容在滚动后将可见;然后使窗口的其余部分无效.

换句话说,您必须跟踪可见的内容.

原生Windows API提供了一个不错的功能:
Having done a number of controls over the years, I''ve always found that the best, and smoothest, way to handle the scrollbar operations is to just to move the contents already painted - if anything you''ve already painted will be visible after scrilling; and then invalidate the rest of the window.

In other words you have to keep track of what''s visible and painted.

The native windows API provides a nice function:
BOOL ScrollDC( HDC hDC,
    int dx,
    int dy,
    const RECT *lprcScroll,
    const RECT *lprcClip,
    HRGN hrgnUpdate,
    LPRECT lprcUpdate
);


这样可以有效地移动您已经绘制的内容-在此处记录 [ ^ ]

我首先要使窗口无效,并增强实现以重用当您使该部分正常工作时所绘制的内容.

问候
Espen Harlinn


That efficiently moves what you''ve already painted - Documented here[^]

I''d start out by just invalidating the window, and enhance the implementation to reuse what''s painted when you''ve got that part working.

Regards
Espen Harlinn


Vlad,对于程序员来说,没有崩溃"之类的东西.您应该正确使用调试器,并且为了为CodeProject发布正确的Question,学习如何转储异常信息.

根据您发布的代码发现此特定问题有点乏味且无聊.我们可以做得更好.让我借助许多开发人员错过的System.Windows.Forms特定异常处理功能为您提供一些帮助;因此它也会对您有所帮助(如果您已经知道的话,请原谅我).最有可能的是,您的所有问题都在您的UI线程中展开.这是您首先要做的.

在入口函数(通常称为Program.Main)中,添加以下行(假设"using System.Windows.Forms;"):

Vlad, for a programmer, there is not such thing as "crashing". You should use debugger properly and, in order to post a correct Question for a CodeProject, learn how to dump exception information.

Spotting this particular problem based on your posted code is a bit tedious and boring. We could do little better. Let me help you a bit with System.Windows.Forms specific exception handling feature which many developers miss; so it will help you in future as well (and please forgive me if you already know that). Most likely, all your problem unfolds in you UI thread. This is what you have to do first.

In your entry point function (usually called Program.Main), add the following line (assuming "using System.Windows.Forms;"):

[System.STAThread]
static void Main() {
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    //...
} //Main



如果在Application.Run的主循环内添加异常时触发的特殊Application事件的某些处理程序.在显示主窗体之前应首先调用此代码,例如,在其构造函数中:



Add some handler of the special Application event fired on exception inside of main loop if Application.Run. This code should be called before you show your main form, as soon as possible, for example, in its constructor:

Application.ThreadException += delegate(
    object sender,
    System.Threading.ThreadExceptionEventArgs eventArgs) {
        System.Windows.Forms.MessageBox.Show(
            string.Format(
                "{0}: \n\n{1}",
                eventArgs.Exception.GetType().Name,
                eventArgs.Exception.Message),
            string.Format(" {0}: Error", Application.ProductName),
            MessageBoxButtons.OK, MessageBoxIcon.Error);
}; //Application.ThreadException



如果您的Framework版本是3.5或更高版本,则lambda形式会更方便:



If your Framework version is 3.5 or later, lambda form is more convenient:

Application.ThreadException += (sender, eventArgs) => {
   //...
}; //Application.ThreadException



这将显示UI线程中的所有异常,而无需终止应用程序,您还可以在此函数中有效地使用调试器断点.


另外或替代地,处理事件System.AppDomain.UnhandledExceptionSystem.AppDomain.FirstChanceException.
我的想法归功于Espen Harlinn.
[END EDIT]

如果没有提供足够的信息,则以递归方式添加详细的dump:异常堆栈(首先要做的事情)以及可能的所有内部异常.如果您需要CodeProject的帮助,请将此转储保存到文件中,并将其内容发布到您的Question中(请尝试格式化!).

如果您的问题仍未解决,请询问后续问题,但不要将其发布为答案(重要!);使用改善问题"或添加评论".

顺便说一句,我不明白为什么要使用P/Invoke,也就是说,为什么纯.NET API不够用?

—SA



This will show all your exceptions in UI thread without termination of the application, you also can effectively use debugger break point in this function.


Additionally or alternatively, handle the events System.AppDomain.UnhandledException and System.AppDomain.FirstChanceException.
My credit to Espen Harlinn for the idea.
[END EDIT]

If it does not provide enough information, add detailed dump: exception stack (first thing to do) and possibly all inner exceptions, recursively. If you want help from CodeProject, save this dump in file and post its content in your Question (please, try to format nicely!).

If your problem is still not resolved, ask follow-up questions, but please not post it as an Answer (important!); use "Improve question" or "Add comment".

By the way, I did not understand why you use P/Invoke, that is, why pure .NET API was not enough?

—SA


这篇关于我如何制作一个在滚动条到达底部时将停止的循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆