Я думаю, что если вы сделаете эту оптимизацию, окно не будет перекрашиваться должным образом после использования кнопок на концах полос прокрутки. По крайней мере, это казалось моим опытом.

 (который происходит отUserControl) имеет возможность отображать горизонтальные и вертикальные полосы прокрутки.ScrollableControlВызывающий может установить видимость и диапазон этих горизонтальных и вертикальных полос прокрутки:

Примечание:

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

  (Т.е.UserControl) использует стандартный механизм указания WindowsScrollableControl а такжеWS_HSCROLL стили окна для отображения полос прокрутки. То есть: они не создают отдельные элементы управления прокруткой Windows или .NET, размещая их справа / снизу окна. В Windows есть стандартный механизм отображения одной или обеих полос прокрутки.WS_VSCROLLЕсли пользователь прокручивает элемент управления,

 отправленоUserControl или жеWM_HSCROLL сообщение. В ответ на эти сообщения я хочу, чтобы ScrollableControl сделал недействительной клиентскую область, что происходит в родном Win32:WM_VSCROLLМне нужно, чтобы вся клиентская область была признана недействительной. Проблема в том, что

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

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

UserControl (Т.е.звонкиScrollableControl)   API функция:ScrollWindowВместо того, чтобы вызывать InvalidateRect на всем клиентском прямоугольнике, ScrollableControl пытается "

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

спасение«существующий контент в клиентской области. Например, пользователь прокручиваетвверхтекущий контент клиента передаетсявниз по, а затем только вновь открытая область становится недействительной, вызываяScrollWindowExНа приведенной выше диаграмме область шахматной доски - это содержимое,WM_PAINT:

инвалид и должен будет быть нарисован во время следующего WM_PAINT.В моем случае это не хорошо; верхняя часть моего элемента управления содержит «заголовок» (например, заголовки столбцов списка). Прокрутка этого контента дальше вниз неверна:

и это вызывает визуальное искажение.

я хочу, чтобы ScrollableControl

не использование, но вместо этого просто сделать недействительной всю клиентскую область.ScrollWindowExя пытался переопределить

 защищенный метод:OnScrollНо это вызывает двойную ничью.

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

   this.Invalidate();
}

Примечание:

 я мог бы использовать двойную буферизацию для маскировки проблемы, но это не реальное решениедвойная буферизация не должна использоваться в сеансе удаленного рабочего стола / терминала

это растрата ресурсов процессораэто не тот вопрос, который я задаюя подумал об использовании

 вместоControl (т.е. раньшеUserControl в цепочке наследования) и вручную добавьте элемент управления HScroll или VScroll .NET, но это также нежелательно:ScrollableControlWindows уже обеспечивает стандартный вид для положения полос прокрутки (дублировать их нетривиально)

это большая функциональность, которую нужно воспроизводить с нуля, когда я хочу толькоInvalidateRect скорее, чемScrollWindowExТак как я могу видеть и опубликовал, код для внутреннего

 я знаю, что нет свойства отключить использованиеScrollableControl, но есть ли свойство отключить использованиеScrollWindowОбновить:ScrollWindow?

я попытался переопределить оскорбительный метод и использовать отражатель, чтобы украсть весь код:

Проблема в том, что

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

SetDisplayRectLocation читает и пишет в закрытую переменную-член (). Если Microsoft не изменит C #, чтобы разрешить потомкам доступ к закрытым членам: я не могу этого сделать.displayRectОбновление Два

я понял, что копирование вставки реализации

, исправляяScrollableControlвопрос означает, что мне также придется скопировать и вставить всю цепочку наследования доя бы действительно предпочел работатьUserControl

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

с участием объектно-ориентированный дизайн, а не против него.Не могли бы вы предоставить скриншоты без ругательств?

Ответы на вопрос(3)

Ваш ответ на вопрос