如何实现自定义控件的滚动?

时间:2014-10-12 05:32:46

标签: c# .net winforms gdi+ gdi

如何为自定义控件实现滚动?我的控件是完全自定义绘制的,其高度是可变的,控件的一部分包含一个菜单,所以如果控件中有很多项,我需要能够在那里放置滚动条。我真的没能找到任何关于如何做到这一点的线索。我确实看到了ScrollableControl的一些内容,但我仍然不确定这是否是我需要的。

另外,我的控件如何知道何时需要显示滚动条?因为我的控件完全是自定义绘制的,所以没有真正的“控件”,只有一堆像素被绘制到它上面所以我不能将AutoScroll设置为true而且我不能这样做,因为它不是需要滚动的控件的主要部分,它是控件上需要有滚动条的特定位置。

4 个答案:

答案 0 :(得分:5)

如果您的自定义控件继承自Panel控件,您只需通过此设置在自定义控件中自行设置内容的大小:

this.AutoScrollMinSize = New Size(yourWidth, yourHeight);

如果您的控件的ClientSize.Height大于yourHeight,则不会获得任何滚动条。如果它更少,那么你会得到一个滚动条。

在paint方法中,将其添加到开头:

protected override void OnPaint(PaintEventArgs e) {
  e.Graphics.TranslateTransform(this.AutoScrollPosition.X,
                                this.AutoScrollPosition.Y);

现在您绘制的所有内容都会自动转换为滚动坐标。

答案 1 :(得分:1)

您有两种选择。

好消息是它有可能并且两者都不是很难。

  • 糟糕的是,对于一个选项,您必须调整所有绘图代码:

首先让您的控件(我使用Panel)拥有Autoscroll=true;

然后你需要添加一个虚拟控件,我使用另一个Panel,也许是这样,远远超过右边和底部强制ScrollBars显示:

public Form1()
{
    InitializeComponent();

    Panel panelDummy = new Panel();
    panelDummy.Size = new Size(1,1);
    panelDummy.Location = new Point(yourMaxX,yourMaxY);
    panel1.Controls.Add(panelDummy);
}

然后你需要调整你的绘图代码。方法如下:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    int xx = panel1.HorizontalScroll.Value;
    int yy = panel1.VerticalScroll.Value;

    e.Graphics.FillRectangle(Brushes.Wheat, new Rectangle(11 - xx, 22 - yy, 22, 311));
    e.Graphics.FillRectangle(Brushes.RosyBrown, new Rectangle(11 - xx, 280 - yy, 22, 3));
}

private void panel1_Scroll(object sender, ScrollEventArgs e)
{
    panel1.Invalidate();
}

我在Invalidate事件中添加了Scroll,以避免混乱的绘画结果。

  • 另一个选项更简单:让你的控件足够大以容纳所有绘制的控件并将其置于<{1}}内Panel AutoScroll=true;这将委托整个滚动业务到包含Panel。

答案 2 :(得分:-1)

您可以Panel使用AutoScroll = true。之后,如果您在其中放置任何控件,只要它们的大小大于面板的大小,面板就会自动显示滚动条..这个技巧可以用于任何自定义控件,只要你放置它在AutoScroll面板中,并根据您的需要调整它的大小。

答案 3 :(得分:-1)

我通过创建一个继承自Control并完全在OnPaint中绘制的自定义控件来部分解决了这个问题。到目前为止,我的解决方案是使用ScrollBarRenderer绘制我的滚动按钮,然后为可滚动区域定义一个Rectangle。然后我创建一个Image来绘制我的可滚动内容,并使用TranslateTransform滚动图像到位置,然后使用DrawImage绘制到我创建的Scrollable Content Rectangle中。它显示出了希望,虽然我还没有完全开始工作,因为我必须自己处理所有的MouseOver和Click事件。