Como impedir que um UserControl (ou seja ScrollableControl) chame o ScrollWindow?

A redeUserControl (que desce deScrollableControl) tem a capacidade de exibir barras de rolagem horizontais e verticai

O chamador pode definir a visibilidade e o alcance dessas barras de rolagem horizontais e verticais:

UserControl.AutoScroll = true;
UserControl.AutoScrollMinSize = new Size(1000, 4000); //1000x4000 scroll area

Nota OUserControl (ou seja,ScrollableControl) usa o mecanismo padrão do Windows para especificarWS_HSCROLL eWS_VSCROLL estilos de janela para fazer aparecer as barras de rolagem. Ou seja: eles não criam controles de rolagem separados para Windows ou .NET, posicionando-os à direita / parte inferior da janela. O Windows possui um mecanismo padrão para exibir uma ou ambas as barras de rolage

Se o usuário rolar o controle, oUserControl é enviado umWM_HSCROLL ouWM_VSCROLL mensagem. Em resposta a essas mensagens, desejo que o ScrollableControl invalide a área do cliente, o que aconteceria no Win32 nativo:

switch (uMsg) 
{ 
   case WM_VSCROLL:
       ...
       GetScrollInfo(...);
       ...
       SetScrollInfo(...);
       ...

       InvalidateRect(g_hWnd, 
              null, //erase entire client area
              true, //background needs erasing too (trigger WM_ERASEBKGND));
       break;
 }

Preciso que toda a área do cliente seja invalidada. O problema é que UserControl (ou seja,ScrollableControl) calls aScrollWindow Função API:

protected void SetDisplayRectLocation(int x, int y)
{
    ...
    if ((nXAmount != 0) || ((nYAmount != 0) && base.IsHandleCreated))
    {
        ...
        SafeNativeMethods.ScrollWindowEx(new HandleRef(this, base.Handle), nXAmount, nYAmount, null, ref rectClip, NativeMethods.NullHandleRef, ref prcUpdate, 7);
    }
    ...
}

Em vez de acionar um InvalidateRect em todo o retângulo do cliente, ScrollableControl tenta "salvament "o conteúdo existente na área do cliente. Por exemplo, o usuário rolaacim, o conteúdo atual do cliente é enviadobaix deScrollWindowEx, e somente a área descoberta recentemente é invalidada, acionando umWM_PAINT:

No diagrama acima, a área quadriculado é o conteúdo que éinválid e terá que ser pintado durante o próximo WM_PAIN

No meu caso, isso não é bom; a parte superior do meu controle contém um "cabeçalho" (por exemplo, cabeçalhos da coluna listview). A rolagem desse conteúdo para baixo está incorreta:

e causa corrupção visual.

Quero que o ScrollableControl seja usarScrollWindowEx, mas invalide toda a área do cliente.

i tentei substituirOnScroll método protegido:

protected override void OnScroll(ScrollEventArgs se)
{
   base.OnScroll(se);

   this.Invalidate();
}

Mas isso causa um empate dupl

Nota Eu poderia usar o buffer duplo para mascarar o problema, mas essa não é uma solução real

buffer duplo não deve ser usado na área de trabalho remota / sessão de terminal é um desperdício de recursos da CPU não é a pergunta que estou fazendo

i considerado usar umControl ao invés deUserControl (ou seja, antes deScrollableControl na cadeia de herança) e adicione manualmente um controle .NET HScroll ou VScroll .NET - mas isso também não é desejável:

O Windows já fornece uma aparência padrão para a posição das barras de rolagem (não é trivial duplicar) há muitas funcionalidades para reproduzir do zero, quando eu só quero InvalidateRect ao invés de ScrollWindowEx

Como posso ver e postar o código interno paraScrollableControl sei que não há propriedade para desativar o uso deScrollWindow, mas existe uma propriedade para desativar o uso deScrollWindow?

Atualizar

i tentei sobrescrever o método ofensivo e use o refletor para roubar todo o código:

protected override void SetDisplayRectLocation(int x, int y)
{
    ...
    Rectangle displayRect = this.displayRect;
    ...
    this.displayRect.X = x;
    this.displayRect.Y = y;
    if ((nXAmount != 0) || ((nYAmount != 0) && base.IsHandleCreated))
    {
        ...
        SafeNativeMethods.ScrollWindowEx(new HandleRef(this, base.Handle), nXAmount, nYAmount, null, ref rectClip, NativeMethods.NullHandleRef, ref prcUpdate, 7);
    }
    ...
}

O problema é que SetDisplayRectLocation lê e grava em uma variável de membro particular displayRect). A menos que a Microsoft altere o C # para permitir que os descendentes acessem membros privados: eu não posso fazer iss

Update Two

i percebi que copiar e colar a implementação deScrollableControl, corrigindo oquestã significa que também terei que copiar e colar toda a cadeia de herança atéUserControl

...
   ScrollableControl2 : Control, IArrangedElement, IComponent, IDisposable
      ContainerControl2 : ScrollableControl2, IContainerControl
         UserControl2 : ContainerControl2

eu realmente prefiro trabalharcoesign orientado a objetos, e não contra el

questionAnswers(3)

yourAnswerToTheQuestion