Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何实现自定义控件的滚动?_C#_.net_Winforms_Gdi+_Gdi - Fatal编程技术网

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

C# 如何实现自定义控件的滚动?,c#,.net,winforms,gdi+,gdi,C#,.net,Winforms,Gdi+,Gdi,如何实现自定义控件的滚动?我的控件是完全自定义绘制的,其高度是可变的,并且控件的一部分包含一个菜单,因此如果控件中有许多项,我需要能够将滚动条放在那里。我还没有找到任何关于如何做这件事的线索。我确实看到了一些关于ScrollableControl,但我仍然不确定这是否是我需要的 另外,我的控件如何知道何时需要显示滚动条?因为我的控件是完全自定义绘制的,所以里面没有真正的“控件”,只是在上面绘制了一堆像素,所以我不能将AutoScroll设置为true,我无论如何也不能这样做,因为它不是需要滚动的

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


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

您可以将
面板
AutoScroll=true
一起使用。之后,如果您将任何控件放入其中,只要它们的大小大于面板的大小,面板将自动显示滚动条。。该技巧也可用于任何自定义控件,只要将其放置在AutoScroll面板中,并根据需要调整其大小。

您有两个选项

好消息是这是可能的,而且两者都不是很难做到

  • 坏消息是,对于一个选项,您必须调整所有图形代码:
首先进行控制,我使用
面板
,使
Autoscroll=true

然后,您需要添加一个虚拟控件,我使用另一个
面板
,可能是这样的,足够到右侧和底部,迫使
滚动条
显示:

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();
}
我在
滚动
事件中添加了一个
无效
,以避免混乱的绘制结果

  • 另一个选项更简单:使控件足够大,以容纳所有绘制的控件,并使用
    AutoScroll=true将其放入
    面板
    这将把整个滚动业务委托给包含面板

如果自定义控件继承自面板控件,则只需通过以下设置在自定义控件中自行设置内容的大小:

this.AutoScrollMinSize = New Size(yourWidth, yourHeight);
如果控件的ClientSize.Height大于yourHeight,则不会获得任何滚动条。如果更少,那么你会得到一个滚动条

在绘制方法中,将以下内容添加到开头:

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

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

我创建了一个自定义控件,该控件继承自control,并完全在OnPaint中绘制,从而部分解决了此问题。到目前为止,我的解决方案是使用ScrollDerrer绘制滚动按钮,然后为可滚动区域定义一个矩形。然后,我创建了一个图像来绘制可滚动内容,并使用TranslateTransform将该图像滚动到位,然后使用DrawImage绘制到我创建的可滚动内容矩形中。它显示出了希望,尽管我还没有让它完全工作,因为我必须自己处理所有鼠标悬停和点击事件

谢谢,但需要滚动的不是整个控件的大小,而是大约四分之一的控件需要滚动条。(想象一个带有按钮的面板控件;单击按钮,然后弹出一个可滚动的菜单)但是,使用您的解决方案,整个控件将滚动,对吗?@jay_t55我专注于您的陈述:
我的控件是完全自定义绘制的…
滚动的部分需要有自己的容器。您解决了问题吗?如果其中任何一个答案有用,你可能想接受它。这个答案没有用。是的,我的控件是完全自定义绘制的,但是,只需要滚动控件的一部分。设想一个带有iframe的网页。您有一个页眉(div)、正文(包含一个滚动iframe)和页脚。页眉和页脚不会滚动,但iframe会滚动,因为它有很多内容。@SE13013然后为页眉、正文和页脚创建不同的面板,只需滚动页脚即可。桌面应用程序和Web应用程序是不同的。