Iorn Man
Iorn Man

Reputation: 267

Scrolling list view when another list view is scrolled

in my win forms app, I am using two List views to compare two files. when user selects two files using folder browser, files are loaded in List views. I compare the files and lines that are not matching are shown with different color. this works absolutely fine. now when I scroll one List view, I want the other List view should also be scrolled with same amount. I tried but you cannot set Horizontal scroll or vertical scroll property of a Listview. how can I do this ? thanks in advance.

Upvotes: 1

Views: 2911

Answers (3)

Fill Freeman
Fill Freeman

Reputation: 199

I had similar task. Two lists that must show theirs items next to each-other.

I found this thread with the Iorn Man's answer, that looked too difficult for me, because I did not have enough experience in C#.

I've found an easier solution for that. I added a timer to a form. For its tick event, I added this:

Form active_form = Form.ActiveForm;
if (active_form == null) return;
Control control = Form.ActiveForm.ActiveControl;
if (control == newFilesList)
{
  Sync_lists(newFilesList);
}
else
{
  Sync_lists(oldFilesList);
}

It checks which list is active and calls Sync_list routine with this list as argument.

private void Sync_lists(ListView sender)
    {
        if ((newFilesList.Items.Count > 0) && (oldFilesList.Items.Count > 0))
        {
            int cur_top_index = sender.TopItem.Index;
            ListViewItem future_top_item;
            if (sender == oldFilesList)
            {
                future_top_item = newFilesList.Items[cur_top_index];
                newFilesList.TopItem = future_top_item;
            }
            else
            {
                future_top_item = oldFilesList.Items[cur_top_index];
                oldFilesList.TopItem = future_top_item;
            }
        }
    }

It just get TopItem property of the base list and sets item with the same index as a top for another list.

It is not so right as a custom ListView. But a little bit simpler. Hope it'll help.

Upvotes: 1

Libor
Libor

Reputation: 3303

You can also do this in Better ListView or Better ListView Express using only managed code:

public class CustomListView : BetterListView
{
    public void SynchronizeScroll(BetterListView listView)
    {
        VScrollBar.Value = listView.VScrollProperties.Value;
    }
}

then handling its VScrollPropertiesChanged event with something like this:

    private void ListViewVScrollPropertiesChanged(object sender, BetterListViewScrollPropertiesChangedEventArgs eventArgs)
    {
        CustomListView listViewThis = (sender as CustomListView);

        listViewThis.SynchronizeScroll(this.listViewAnother);
    }

Upvotes: 0

Iorn Man
Iorn Man

Reputation: 267

you need to create a custom List view so that you can detect it scrolling and pass the scroll message to the other text box so it will scroll in sync.

 class SyncListView: ListView
{
    public SyncListView()
    {
    }

    public Control Buddy { get; set; }

    private static bool scrolling;   // In case buddy tries to scroll us

    protected override void WndProc(ref Message m) 
    {
    base.WndProc(ref m);
    // Trap WM_VSCROLL message and pass to buddy
    if ((m.Msg == 0x115 || m.Msg == 0x20a) && !scrolling && Buddy != null && Buddy.IsHandleCreated)
    {
        scrolling = true;
        SendMessage(Buddy.Handle, m.Msg, m.WParam, m.LParam);
        scrolling = false;
    }
}

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

}

Upvotes: 2

Related Questions