Подтвердить что ты не робот

Как вы можете пропустить прокрутку панели Winforms?

Если вы установите DataGridView на высоту 400 пикселей на панель высотой 300 пикселей, чтобы на панели была прокрутка, затем прокрутите вниз, чтобы отобразилась нижняя половина сетки, затем нажмите кнопку управления вне панели, затем щелкните по строке в сетке, панель прокручивается вверх и выбирается неправильная строка в сетке.

Это не просто DataGridView; это происходит с любым элементом управления, который выше, чем панель, например Infragistics UltraWinGrid, Rich Text Box. Я поднял его как ошибку с Infragistics, но они говорят, что это проблема Microsoft.

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

Любые предложения?

4b9b3361

Ответ 1

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

Если вы отключите AutoScroll и добавьте свою собственную полосу прокрутки, вы можете установить максимальную и минимальную ширину полосы прокрутки в соответствии с требованиями к панели, а затем установить значения прокрутки панели в событии "Прокрутка" полосы прокрутки. Это не reset при переключении окон.

Что-то вроде:

private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
{
    panel1.VerticalScroll.Value = vScrollBar1.Value;
}

Это было новое для меня, и мне пришлось его воссоздать. Возможно, мне придется добавить статью на мой сайт: -)

Ответ 2

Это вызвано тем, что событие ScrollToControl автоматически запускается классом ScrollableControl, а прокрутка обработчика событий отображает левый верхний элемент элемента управления, который получил фокус. Такое поведение не помогает, когда элемент управления с прокруткой содержит только один элемент управления. Я был очень расстроен этим поведением, пока не узнал, как остановить его.

Способ остановить это поведение - переопределить обработчик событий ScrollToControl, например:

class PanelNoScrollOnFocus : Panel
{
    protected override System.Drawing.Point ScrollToControl(Control activeControl)
    {
        return DisplayRectangle.Location;
    }
}

Замените панель управления этим элементом управления панелью. Готово.

Ответ 3

Спасибо Skypecakes, это прекрасно работает :) Вот отредактированная версия вашего элемента управления, которая также отслеживает, где полосы прокрутки, где:

class AutoScrollPanel : Panel
{
    public AutoScrollPanel()
    {
        Enter += PanelNoScrollOnFocus_Enter;
        Leave += PanelNoScrollOnFocus_Leave;
    }

    private System.Drawing.Point scrollLocation;

    void PanelNoScrollOnFocus_Enter(object sender, System.EventArgs e)
    {
        // Set the scroll location back when the control regains focus.
        HorizontalScroll.Value = scrollLocation.X;
        VerticalScroll.Value = scrollLocation.Y;
    }

    void PanelNoScrollOnFocus_Leave(object sender, System.EventArgs e)
    {
        // Remember the scroll location when the control loses focus.
        scrollLocation.X = HorizontalScroll.Value;
        scrollLocation.Y = VerticalScroll.Value;
    }

    protected override System.Drawing.Point ScrollToControl(Control activeControl)
    {
        // When there only 1 control in the panel and the user clicks
        //  on it, .NET tries to scroll to the control. This invariably
        //  forces the panel to scroll up. This little hack prevents that.
        return DisplayRectangle.Location;
    }
}

Это работает, только если в Panel есть только один элемент управления (хотя я не тестировал его с более чем одним элементом управления).

Ответ 4

Да, я обнаружил, что создание нового класса панели Dock для Fill остановило прыжки вокруг, поэтому, к счастью, не нужно запоминать и восстанавливать ScrollLocation при вводе и выводе событий.

Ответ 5

Я понимаю вашу боль, это привело меня не один раз.

Если ваш DataGridView является единственной вещью в панели, просто установите Dock для заполнения и пусть ручка DGV прокручивается на ней. Я не думаю, что он будет делать прыжки. В противном случае, я думаю, вы могли бы просто настроить его так, чтобы он был меньше, чем панель, и пусть это делает прокрутку на нем.