如何禁用Panel中的水平滚动条

34

我有一个面板(Windows Forms),我想禁用面板的水平滚动条。我尝试了这个:

HorizontalScroll.Enabled = false;

但是那样行不通。

我该如何做到这一点?


类似问题:https://dev59.com/S0nSa4cB1Zd3GeqPKgog - Rion Williams
11个回答

84

尝试按照这种方式实现,它将100%可行。

panel.HorizontalScroll.Maximum = 0;
panel.AutoScroll = false;
panel.VerticalScroll.Visible = false;
panel.AutoScroll = true;

9
这应该是被采纳的答案。其他的方法对我没有用,但这个简单的代码实际上解决了我的问题! - Anonymous Pi
9
非常重要的一点是,我一直卡在上面!请确保在设计模式下将“AutoScroll”属性设置为FALSE,否则这将无法正常工作。 - Arvo Bowen
4
这是什么巫术...那些指令的顺序毫无逻辑可言。但它能用... - Hill
1
如果在设计模式下设置了AutoScroll为true,则应将“panel.AutoScroll = false;”放在块的第一行。然后它对我来说完美地工作了。 - Brian Cryer
1
设置 VerticalScroll.VisibleHorizontalScroll.Visible 是无关紧要的。只需将 AutoScroll = false,将 VerticalScroll.Maximum 和/或 VerticalScroll.Maximum 设置为 0,最后重置 AutoScroll = true 即可。-- 您将无法控制滚动范围。 - Jimi
显示剩余4条评论

23

如果您觉得想要毁坏你的代码,那么您可以尝试这个非常“hackish”的解决方案:

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ShowScrollBar(IntPtr hWnd, int wBar, bool bShow);

private enum ScrollBarDirection
{
    SB_HORZ = 0,
    SB_VERT = 1,
    SB_CTL = 2,
    SB_BOTH = 3
}

protected override void WndProc(ref System.Windows.Forms.Message m)
{
    ShowScrollBar(panel1.Handle, (int)ScrollBarDirection.SB_BOTH, false);
    base.WndProc(ref m);
}

我目前使用上面的代码来防止第三方用户控件显示滚动条。它们没有提供任何合适的方法来隐藏它们。


好吧,我不认为它对我有用,我做了一个小测试并使用了它,一个面板就消失了,另一个仍然有滚动条。无论如何,谢谢 :) - Eli Braginskiy
5
非常好!虽然 WndProc 部分肯定不需要。只需调用: ShowScrollBar(panel1.Handle, (int)ScrollBarDirection.SB_HORZ, false);从任何你想要隐藏滚动条的其他方法中即可! - BrainSlugs83
关闭表单时在Win 2008服务器上显示错误! - Tamilmaran

14

我认为你遇到这个问题是因为你的面板(panel)的AutoScroll属性设置为True。我创建了一个测试方案(.NET 3.5),发现以下事项:

如果你尝试这样做:

panel.AutoScroll = true;
panel.HorizontalScroll.Enabled = false;
panel.HorizontalScroll.Visible = false;

如果面板内有控件会导致自动滚动条显示,那么HorizontalScroll.Enabled和.Visible属性不会被改变为false。似乎你必须先禁用AutoScroll才能手动更改这些属性。


Visual Studio 提示该面板没有 HScrollProperties,你确定它有吗? - Eli Braginskiy
抱歉,尝试将HScroll = false; - Dave M
它也没有,我正在尝试从面板而不是表单中将其移除。 - Eli Braginskiy
@Dave - 我所知道的面板滚动唯一的属性是AutoScroll,它控制水平和垂直滚动。 - Joel Lee
@Blue Gene,你的AutoScroll = true吗? - Dave M
我在测试解决方案中搞砸了AutoScroll属性,修改了答案。 - Dave M

7

我曾经也遇到过这种问题,当AutoScroll=true时,水平滚动条会出现,只有当垂直滚动条出现时才会显示。后来我发现,是因为我从面板中删除了填充,通过在右侧添加20的填充,可以让垂直滚动条出现而不显示水平滚动条。


1
我有一个可滚动的TableLayoutPanel,停靠在其父容器上,并且只需向TableLayoutPanel添加20px的右填充即可解决问题(水平滚动条不再出现)。 - Rachel

2

SuperOli的回答非常好!

我更新了代码,现在可以关闭表单而不会出现任何错误。
希望对你也有用。

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ShowScrollBar(IntPtr hWnd, int wBar, bool bShow);

private enum ScrollBarDirection
{
    SB_HORZ = 0,
    SB_VERT = 1,
    SB_CTL = 2,
    SB_BOTH = 3
}

protected override void WndProc(ref System.Windows.Forms.Message m)
{
    if (m.Msg == 0x85) // WM_NCPAINT
    {                
        ShowScrollBar(panel1.Handle, (int)ScrollBarDirection.SB_BOTH, false);
    }

    base.WndProc(ref m);
}

1

使用托管 C++ 代码隐藏 HScroll Bar:

// Hide horizontal scroll bar
HWND h = static_cast<HWND> (this->Handle.ToPointer());
ShowScrollBar(h, SB_HORZ, false);

1
Console.BufferHeight = 44;

将缓冲区高度设置为控制台窗口高度。在我的程序中,我给出了静态高度,但您也可以这样做:

Console.BufferHeiht = (Console.WindowHight - 1);

我认为它应该可以工作。


0

我正在寻找如何在需要时添加滚动条并在不需要时删除它的答案。这是我为文本框提供的解决方案,具有最大允许的宽度和高度,并根据显示的文本进行调整大小。

private void txtOutput_TextChanged(object sender, EventArgs e)
    {
        // Set the scrollbars to none. If the content fits within textbox maximum size no scrollbars are needed. 
        txtOutput.ScrollBars = ScrollBars.None;

        // Calculate the width and height the text will need to fit inside the box
        Size size = TextRenderer.MeasureText(txtOutput.Text, txtOutput.Font);

        // Size the box accordingly (adding a bit of extra margin cause i like it that way)
        txtOutput.Width = size.Width + 20;
        txtOutput.Height = size.Height + 30;


        // If the box would need to be larger than maximum size we need scrollbars

        // If height needed exceeds maximum add vertical scrollbar
        if (size.Height > txtOutput.MaximumSize.Height)
        {

            txtOutput.ScrollBars = ScrollBars.Vertical;

            // If it also exceeds maximum width add both scrollbars 
            // (You can't add vertical first and then horizontal if you wan't both. You would end up with just the horizontal) 
            if (size.Width > txtOutput.MaximumSize.Width)
            {
                txtOutput.ScrollBars = ScrollBars.Both;
            }
        }

        // If width needed exceeds maximum add horosontal scrollbar 
        else if (size.Width > txtOutput.MaximumSize.Width)
        {
            txtOutput.ScrollBars = ScrollBars.Horizontal;
        }
    }

0

当我从滚动模式切换到适合缩放模式时,在窗体中的可滚动UserControl遇到了同样的故障。对于后一种模式,两个滚动条都应该关闭。大多数情况下,这种模式的更改都能完美地工作,除非其中一个或两个滚动条处于最大值,导致其中一个或另一个滚动条保持可见但被禁用。

似乎是随机显示哪个滚动条保持可见,因此Windows代码中必须存在某种竞争条件。

有趣的是,Windows报告的ClientRectangle是没有任何滚动条的UserControl的完整矩形。这意味着Windows认为滚动条不可见,但仍然随机显示一个或另一个禁用的滚动条。

在执行切换到适合缩放模式之前,我通过将AutoScrollPosition移动到(0, 0)来解决了这个问题。

AutoScrollPosition = new Point(0, 0);  // Bug fix to prevent one or other of the scrollbars randomly remaining visible when switching to zoom-to-fit mode when the scrollbars are at their maximum values.
zoom_factor = CalcZoomFactorBestFit();
SetScrollSizes();
Invalidate();

0
根据@Guesting提出的代码,我编写了一个自定义类来控制面板,以启用双缓冲选项,并且还可以启用/禁用每个滚动条。
   Public Class PanelDoubleBuffer
    Inherits Panel

    'MAIN LAYOUT design scheme
    Public Property ShowVerticalScrolBar As Boolean = False
    Public Property ShowHorizontalScrolBar As Boolean = False

    Public Sub New()
        SuspendLayout()

        SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        SetStyle(ControlStyles.UserPaint, True)

        SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
        SetStyle(ControlStyles.SupportsTransparentBackColor, True)
        SetStyle(ControlStyles.ResizeRedraw, True)
        Me.UpdateStyles()

        ResumeLayout()
    End Sub

    <DllImport("user32.dll")>
    Private Shared Function ShowScrollBar(ByVal hWnd As IntPtr, ByVal wBar As Integer, ByVal bShow As Boolean) As Boolean
    End Function

    Public Property SB_HORZ As Integer = ShowHorizontalScrolBar
    Public Property SB_VERT As Integer = ShowVerticalScrolBar
    Public Property SB_CTL As Integer = 2
    Public Property SB_BOTH As Integer = 3

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If m.Msg = &H85 Then
            ShowScrollBar(Me.Handle, CInt(SB_BOTH), False)
        End If

        MyBase.WndProc(m)
    End Sub
End Class

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接