Scroll 2 panels at the same time

2019-06-25 09:49发布

I have windows forms (.net 2.0) control that contains a splicontainer inside. Splitcontainer, as usually, contains 2 panels (standard thing). The Autoscroll is set to true.

I've been struggling for quite a time to achieve something like synchronizing those two panels, so scrolling one of these will scroll the second one also. I achieved it - using Scroll event (not a problem).

However, this event is not called when we're tabbing through controls on the one of the panels (e.g. textboxes) - not really like what it's on the msdn.microsoft.com/en-us/library/system.windows.forms.scrollablecontrol.scroll.aspx ("The Scroll event occurs when the user scrolls through the client area by interacting with the scroll bars, or when the user navigates between controls and the active control scrolls into view. ".

So, in fact, the panels are not really synchronized :|

I'm aware of the fact, that giving focus to not visible control contained in a scrollable control calls it's ScrollToControl(Control) event which "makes" the new control(textbox) visible. To give more details, I can say that both panels are identical (size and controls).

How would you achieve what I'm looking for?

3条回答
神经病院院长
2楼-- · 2019-06-25 10:09

Why don't you place the split container completely in a scrolling thingy instead of putting the scrollbar thingies inside the split container? That way they naturally share the same scrollbar and the split container can be as wide as necessary to fit the entire form.

查看更多
别忘想泡老子
3楼-- · 2019-06-25 10:25

I took the answer from @SwDevMan81 and rounded it out with the last piece I needed to get it work in VS 2012, .Net 4.5.

Part 1 is inside my form class:

    #region Synchronize the scrolling of the two panels in the SplitContainer.

    private Point _prevPan1Pos = new Point();
    private Point _prevPan2Pos = new Point();

    void PanelPaint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        SynchronizeSplitContainerScrollbars();
    }

    private void SynchronizeSplitContainerScrollbars()
    {
        if (splitContainer1.Panel1.AutoScrollPosition != _prevPan1Pos)
        {
            splitContainer1.Panel2.AutoScrollPosition = new System.Drawing.Point(-splitContainer1.Panel1.AutoScrollPosition.X, -splitContainer1.Panel1.AutoScrollPosition.Y);
            _prevPan1Pos = splitContainer1.Panel1.AutoScrollPosition;
        }
        else if (splitContainer1.Panel2.AutoScrollPosition != _prevPan2Pos)
        {
            splitContainer1.Panel1.AutoScrollPosition = new System.Drawing.Point(-splitContainer1.Panel2.AutoScrollPosition.X, -splitContainer1.Panel2.AutoScrollPosition.Y);
            _prevPan2Pos = splitContainer1.Panel2.AutoScrollPosition;
        } 
    }

    #endregion

Part 2 is in the constructor for the Form. I had to add events for the Scroll events themselves.

        // Setup so we can synchronize the scrolling of the two panels in the SplitContainer.
        splitContainer1.Panel1.Paint += PanelPaint;
        splitContainer1.Panel2.Paint += PanelPaint;
        splitContainer1.Panel1.Scroll += (obj, scrollEventArgs) => SynchronizeSplitContainerScrollbars();
        splitContainer1.Panel2.Scroll += (obj, scrollEventArgs) => SynchronizeSplitContainerScrollbars();
查看更多
手持菜刀,她持情操
4楼-- · 2019-06-25 10:26

Here is exactly what you need to scroll 2 panels in a SplitContainer. This will scroll even if you are tabbing to controls not in the current view.


this.splitContainer1.Panel1.Paint += new System.Windows.Forms.PaintEventHandler(PanelPaint);
this.splitContainer1.Panel2.Paint += new System.Windows.Forms.PaintEventHandler(PanelPaint);

Point mPrevPan1Pos = new Point();
Point mPrevPan2Pos = new Point();

void PanelPaint(object sender, System.Windows.Forms.PaintEventArgs e)
{
   if (splitContainer1.Panel1.AutoScrollPosition != mPrevPan1Pos)
   {
      splitContainer1.Panel2.AutoScrollPosition = new System.Drawing.Point(-splitContainer1.Panel1.AutoScrollPosition.X, -splitContainer1.Panel1.AutoScrollPosition.Y);
      mPrevPan1Pos = splitContainer1.Panel1.AutoScrollPosition;
   }
   else if (splitContainer1.Panel2.AutoScrollPosition != mPrevPan2Pos)
   {
      splitContainer1.Panel1.AutoScrollPosition = new System.Drawing.Point(-splitContainer1.Panel2.AutoScrollPosition.X, -splitContainer1.Panel2.AutoScrollPosition.Y);
      mPrevPan2Pos = splitContainer1.Panel2.AutoScrollPosition;
   }
}
查看更多
登录 后发表回答