Синхронная прокрутка нескольких listbox winforms c#

158
01 января 2022, 03:40

Есть 4 листбокса в winforms, количество айтемов там всегда одинаковое, как сделать синхронную прокрутку с клавиатуры(стрелок), колесика мышки и ползунка. Ползунок нужно оставить только на одном из листбоксов. Заранее спасибо!

Answer 1

Вам следует подписаться на событие прокрутки на том ListBox на котором идёт прокрутка, а в обработчике этого события задавать значения TopIndex остальным спискам (значение должно быть такое же, как и у главного).

В нашем случае у ListBox из WinForms нет своего события скроллинга, поэтому будем улучшать наш список:

using System;
using System.Windows.Forms;
public class BetterListBox : ListBox 
{
// Event declaration
    public delegate void BetterListBoxScrollDelegate(object Sender, 
    BetterListBoxScrollArgs e);
    public event BetterListBoxScrollDelegate Scroll;
    // WM_VSCROLL message constants
    private const int WM_VSCROLL = 0x0115;
    private const int SB_THUMBTRACK = 5;
    private const int SB_ENDSCROLL = 8;
    protected override void WndProc(ref Message m)
    {
    // Trap the WM_VSCROLL message to generate the Scroll event
    base.WndProc(ref m);
    if (m.Msg == WM_VSCROLL) {
        int nfy = m.WParam.ToInt32() & 0xFFFF;
        if (Scroll != null && (nfy == SB_THUMBTRACK || nfy == SB_ENDSCROLL))
        Scroll(this, new BetterListBoxScrollArgs(this.TopIndex, nfy == SB_THUMBTRACK));
    }
}
public class BetterListBoxScrollArgs
{
    // Scroll event argument
    private int mTop;
    private bool mTracking;
    public BetterListBoxScrollArgs(int top, bool tracking)
    {
        mTop = top;
        mTracking = tracking;
    }
    public int Top 
    {
        get { return mTop; }
    }
    public bool Tracking 
    {
        get { return mTracking; }
    }
}

Очевидно, что теперь нам будет проще добавлять наш улучшенный ListBox только через код.

Делается это несложно:

var list1 = new BetterListBox();
list1.Width = 200;
list1.Height = 200;
Controls.Add(list1);

Теперь подпишемся на событие:

list1.Scroll += BetterListBox1_Scroll;

Где BetterListBox1_Scroll - это наш обработчик события:

void BetterListBox1_Scroll(object s, BetterListBoxScrollArgs e)
{
    // здесь будут наши обновления других списков
}

Обновим остальные списки:

void BetterListBox1_Scroll(object s, BetterListBoxScrollArgs e)
{
    list4.TopIndex = list3.TopIndex = list2.TopIndex = list1.TopIndex;
}

Готово! Некоторые моменты проверил лично, но не все, поэтому могут возникнуть непредвиденные трудности, на счет них либо спрашивать, либо искать в интернетах, а знающим править найденную ошибку.

P.s.: Если есть возможность и желание, то лучше воспользоваться готовыми решениями, которое подразумевают то же самое и более пригодны для ТЗ, то есть таблицами.

Источник

READ ALSO
Проблема с выводом значения по умолчанию

Проблема с выводом значения по умолчанию

Я написал запрос и он работает верно, но когда дело дошло до добавления значения по умолчанию, я получаю ошибку:

83
Передвижение объекта Touch.position

Передвижение объекта Touch.position

Введение: 2D проект, в котором есть два SpriteПервый передвигается в позицию касанию на экран (Touch), Второй же перемещается/отдаляется к Первому

102
Перетаскивание формы за любое место (контролы в том числе) + закрытие по клику на любое место

Перетаскивание формы за любое место (контролы в том числе) + закрытие по клику на любое место

Имеется форма без рамок с одним элементом axWindowsMediaPlayerПо сути, что то типа окна плеера

80