Как программно прокручивать панель

У меня есть System.Windows.Forms.Panel с некоторым контентом.

Я пытаюсь программно прокручивать панель (вертикально) вверх или вниз.

Я попытался установить свойство AutoScrollPosition на новый Point на панели, но это не похоже на это.

У меня есть свойство AutoScroll, равное true.

Я даже пытался установить VerticalScroll.Value дважды, как предлагалось здесь, но это тоже не работает.

Это то, что я сейчас делаю:

//I have tried passing both positive and negative values.
panel.AutoScrollPosition = new Point(5, 10);

Значения X и Y в AutoScrollPosition остаются 0 и 0.

Любая помощь или руководство по этому поводу будут очень благодарны.

Спасибо заранее,

Марван

Ответ 1

Вот решение. Я думаю, вы можете прокручивать Panel по произвольной позиции с помощью Win32, но есть простой трюк, который поможет вам выполнить ваше требование здесь:

public void ScrollToBottom(Panel p){
  using (Control c = new Control() { Parent = p, Dock = DockStyle.Bottom })
     {
        p.ScrollControlIntoView(c);
        c.Parent = null;
     }
}
//use the code
ScrollToBottom(yourPanel);

Или используйте метод расширения для удобства:

public static class PanelExtension {
   public static void ScrollToBottom(this Panel p){
      using (Control c = new Control() { Parent = p, Dock = DockStyle.Bottom })
      {
         p.ScrollControlIntoView(c);
         c.Parent = null;
      }
   }
}
//Use the code
yourPanel.ScrollToBottom();

UPDATE

Если вы хотите установить точную позицию, небольшое изменение кода может помочь:

//This can help you control the scrollbar with scrolling up and down.
//The position is a little special.
//Position for scrolling up should be negative.
//Position for scrolling down should be positive
public static class PanelExtension {
    public static void ScrollDown(this Panel p, int pos)
    {
        //pos passed in should be positive
        using (Control c = new Control() { Parent = p, Height = 1, Top = p.ClientSize.Height + pos })
        {
            p.ScrollControlIntoView(c);                
        }
    }
    public static void ScrollUp(this Panel p, int pos)
    {
        //pos passed in should be negative
        using (Control c = new Control() { Parent = p, Height = 1, Top = pos})
        {
            p.ScrollControlIntoView(c);                
        }
    }
}
//use the code, suppose you have 2 buttons, up and down to control the scrollbar instead of clicking directly on the scrollbar arrows.
int i = 0;
private void buttonUp_Click(object sender, EventArgs e)
{
   if (i >= 0) i = -1;
   yourPanel.ScrollUp(i--);
}
private void buttonDown_Click(object sender, EventArgs e)
{
   if (i < 0) i = 0;
   yourPanel.ScrollDown(i++);
}

Другим решением, которое вы можете использовать, является использование Panel.VerticalScroll.Value. Однако я думаю, вам нужно больше исследований, чтобы заставить его работать так, как вы ожидаете. Поскольку я вижу, как только меняют Value, положение полосы прокрутки и позиция управления не синхронизируются хорошо. Обратите внимание, что Panel.VerticalScroll.Value должно быть между Panel.VerticalScroll.Minimum и Panel.VerticalScroll.Maximum.

Ответ 2

Если у вас есть класс, который происходит от Panel, затем вызовите эти два защищенных метода для прокрутки панели:

// The bottom is off screen; scroll down. These coordinates must be negative or zero.
SetDisplayRectLocation(0, AutoScrollPosition.Y - item.BoundingRect.Bottom + ClientRectangle.Bottom);
AdjustFormScrollbars(true);

В моем примере item.BoundingRect.Bottom - это координата Y нижней части миниатюры, и мне нужно прокрутить панель вниз, чтобы весь значок был виден.

@King King решение создания временного элемента управления просто для того, чтобы прокрутка могла быть выполнена, казалось мне "тяжелой". И предложение @Hans Passant установки AutoScrollMinSize и AutoScrollPosition не помогло мне.

Оставьте AutoScroll значение по умолчанию "true".

Ответ 3

Попробуйте следующее:   panel.ScrollControlIntoView(childcontrol);

Это должно сработать. childcontrol - это особый элемент управления, который вы хотите показать в области отображения.

Ответ 4

Это удивительно работает! ЗАМЕТЬТЕ ЗНАК МИНУС в коде. При настройке положения прокрутки происходит странное поведение. Если вы установите точное значение (50), оно станет отрицательным при следующем чтении (-50). Таким образом, вы должны инвертировать его перед установкой нового значения прокрутки.

Прокрутить вниз:

private void ButtonScrollDown_OnClick(object sender, EventArgs e)
{
    Point current = yourScrollPanel.AutoScrollPosition;
    Point scrolled = new Point(current.X, -current.Y + 10);
    yourScrollPanel.AutoScrollPosition = scrolled;
}

Аналогично прокрутите вверх, (-current.Y - 10)

Ответ 5

Используйте @King King Answered Code, и если вы хотите скрыть горизонтальную и вертикальную полосу прокрутки, просто примените приведенный ниже код в конструкторе или инициализации.

        yourPanel.AutoScroll = false;
        yourPanel.HorizontalScroll.Maximum = 0;
        yourPanel.HorizontalScroll.Visible = false;
        yourPanel.VerticalScroll.Maximum = 0;
        yourPanel.VerticalScroll.Visible = false;
        yourPanel.AutoScroll = true;

Ответ 6

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

Nomatter, что я сделал, всегда помещал панель VScroll в начало.

После исчерпывающего тестирования я обнаружил, что это связано с тем, что у моего элемента управления было установлено свойство TabStop, равное true (по умолчанию для пользовательских элементов управления).

Настройка TabStop на false исправила его.

Ответ 7

Создайте элемент управления, который находится немного за пределами видимой области (например, -1 вверху и размер клиента + 1), а затем вызовите ScrollControlIntoView:

public static class PanelExtension {
public static void ScrollDown(this Panel p)
{

    using (Control c = new Control() { Parent = p, Height = 1, Top = p.ClientSize.Height + 1 })
    {
        p.ScrollControlIntoView(c);                
    }
}
public static void ScrollUp(this Panel p )
{

    using (Control c = new Control() { Parent = p, Height = 1, Top = -1})
    {
        p.ScrollControlIntoView(c);                
    }
}
}
    //use the code, suppose you have 2 buttons, up and down to control the scrollbar instead of clicking directly on the scrollbar arrows.

        private void buttonUp_Click(object sender, EventArgs e)
{

   yourPanel.ScrollUp();
}
private void buttonDown_Click(object sender, EventArgs e)
{

   yourPanel.ScrollDown();
}

с вашей панелью. SetAutoScrollMargin (1, 1); Вы можете установить очень точные шаги прокрутки, а затем использовать таймер для вызова прокрутки при нажатии кнопок