Pergunta

I am working on a mobile application UI that has a panel with momentum (for smooth scrolling) and I am currently updating the UI durring the smooth scrolling by using the following code:

private void scrollKinetic()
{
    while (_curState == States.KineticScroll)
    {
        //  This gets how far the panel will move with the current velocity, then updates the velocity according to the current friction.
        var distY = GetDistance(scrVelocity.Y);
        var distX = GetDistance(scrVelocity.X);

        if (distY + distX <= 0)  //  Friction will eventually make distX and distY both 0
        {
            _curState = States.Idle;
            Invalidate();
            break;
        }

        //  CalculatePosition will move the panel accordingly.

        CalculatePosition(distY, scrVelocity.Y, false);
        CalculatePosition(distX, scrVelocity.X, true);

        Invalidate();
        friction++;
        Application.DoEvents();
    }
}

As you can see, Application.DoEvents(); is rearing its ugly head! I want to get rid of it, but I can't think of any way to loop and update the UI. Any help/ideas would be excellent!

I'm doing this on the .net CF, but I think it's a design issue, so I don't think the platform will matter too much.

Foi útil?

Solução 2

You could try and remove the loop (and all App.DoEvent calls), make a call to KineticScroll in your OnPaint() method, and then call Invalidate() in your KineticScroll method.

I see that you have some kind of state tracking, so you can say something like:

if(_curState == States.KineticScroll)
    KineticScroll();

in your OnPaint() method, that way you only call it when your state is approprate.

Basically, your loop goes from a local while loop to: OnPaint -> KineticScroll -> Invalidate -> OnPaint...etc that way you get the same loop, w/o making a call to DoEvents!

Outras dicas

I'd create a timer that would act like a "game loop" -- execute x times per second.
I would also keep track of how much time elapsed since the last call so that you can calculate how much to move based on that time elapsed. For extra performance, the timer could be started and stopped only if there is motion.

Depending on what kind of timer you use, you may need to marshal your UI update calls back to the UI thread.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top