You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Visual Studio 2022 VB.Net如何制作带标尺和页面边框的窗体应用

VB.Net WinForm 实现标尺+页面边框效果

问题背景

开发环境:Visual Studio 2022 + VB.Net Windows 窗体应用框架
需求:实现类似Office文档编辑区的标尺、带阴影的页面边框效果,效果参考下图:
标尺与页面边框效果预览

实现思路

完全基于原生GDI+自定义绘图实现,不需要引入第三方控件,核心是在容器控件的Paint事件里分层绘制标尺、页面、阴影、刻度元素,开启双缓冲避免绘图闪烁即可。

具体实现步骤

  • 第一步:搭建基础画布
    从工具箱拖一个Panel控件到窗体,命名为printCanvas,作为绘图的容器。在窗体构造函数里通过反射开启Panel的双缓冲,避免拖动、缩放时的闪烁问题,代码如下:
    Public Sub New()
        InitializeComponent()
        ' 开启Panel双缓冲,默认属性面板不暴露该配置
        Dim doubleBufferProp = GetType(Panel).GetProperty(
            "DoubleBuffered",
            Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic
        )
        doubleBufferProp.SetValue(printCanvas, True, Nothing)
    End Sub
    
  • 第二步:编写Paint事件绘图逻辑
    给printCanvas绑定Paint事件,按「页面阴影→页面白底+边框→标尺背景→标尺刻度」的顺序绘制,避免图层覆盖。核心代码如下:
    Private Sub printCanvas_Paint(sender As Object, e As PaintEventArgs) Handles printCanvas.Paint
        Dim g As Graphics = e.Graphics
        g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
        g.Clear(Color.FromArgb(240, 240, 240)) ' 画布背景设为浅灰
    
        ' 固定配置项 可根据自己的需求调整
        Const RulerSize As Integer = 32 ' 水平/垂直标尺的宽/高
        Const PageGap As Integer = 25 ' 标尺和页面之间的间距
        Const PageShadowOffset As Integer = 4 ' 页面阴影偏移量
        Dim pageSize As New Size(850, 1202) ' 页面尺寸 按A4比例(1:√2)设置即可
    
        ' 计算页面所在的矩形区域
        Dim pageRect As New Rectangle(
            RulerSize + PageGap,
            RulerSize + PageGap,
            pageSize.Width,
            pageSize.Height
        )
    
        ' 1. 绘制页面阴影
        g.FillRectangle(Brushes.Gainsboro,
                        pageRect.X + PageShadowOffset,
                        pageRect.Y + PageShadowOffset,
                        pageRect.Width,
                        pageRect.Height)
        ' 2. 绘制页面白底+黑色边框
        g.FillRectangle(Brushes.White, pageRect)
        g.DrawRectangle(Pens.Black, pageRect)
    
        ' 3. 绘制水平标尺
        Dim hRulerRect As New Rectangle(RulerSize, 0, pageSize.Width, RulerSize)
        g.FillRectangle(Brushes.WhiteSmoke, hRulerRect)
        g.DrawLine(Pens.Gray, hRulerRect.Left, hRulerRect.Bottom - 1, hRulerRect.Right, hRulerRect.Bottom - 1)
        ' 毫米转像素 按当前系统DPI计算,96DPI下1毫米≈3.78像素
        Dim mm2Px As Single = g.DpiX / 25.4F
        For mm = 0 To CInt(pageSize.Width / mm2Px)
            Dim drawX As Single = hRulerRect.X + mm * mm2Px
            Select Case mm Mod 10
                Case 0
                    ' 1厘米长刻度+数值标注
                    g.DrawLine(Pens.Black, drawX, hRulerRect.Bottom, drawX, hRulerRect.Bottom - 12)
                    g.DrawString((mm / 10).ToString(),
                                New Font("微软雅黑", 8F),
                                Brushes.Black,
                                drawX - 9, 2)
                Case 5
                    ' 5毫米中刻度
                    g.DrawLine(Pens.Black, drawX, hRulerRect.Bottom, drawX, hRulerRect.Bottom - 7)
                Case Else
                    ' 1毫米短刻度
                    g.DrawLine(Pens.Black, drawX, hRulerRect.Bottom, drawX, hRulerRect.Bottom - 3)
            End Select
        Next
    
        ' 4. 绘制垂直标尺
        Dim vRulerRect As New Rectangle(0, RulerSize, RulerSize, pageSize.Height)
        g.FillRectangle(Brushes.WhiteSmoke, vRulerRect)
        g.DrawLine(Pens.Gray, vRulerRect.Right - 1, vRulerRect.Top, vRulerRect.Right - 1, vRulerRect.Bottom)
        For mm = 0 To CInt(pageSize.Height / mm2Px)
            Dim drawY As Single = vRulerRect.Y + mm * mm2Px
            Select Case mm Mod 10
                Case 0
                    ' 1厘米长刻度+竖排数值标注
                    g.DrawLine(Pens.Black, vRulerRect.Right, drawY, vRulerRect.Right - 12, drawY)
                    g.TranslateTransform(vRulerRect.X + 12, drawY + 9)
                    g.RotateTransform(-90)
                    g.DrawString((mm / 10).ToString(),
                                New Font("微软雅黑", 8F),
                                Brushes.Black,
                                0, 0)
                    g.ResetTransform()
                Case 5
                    ' 5毫米中刻度
                    g.DrawLine(Pens.Black, vRulerRect.Right, drawY, vRulerRect.Right - 7, drawY)
                Case Else
                    ' 1毫米短刻度
                    g.DrawLine(Pens.Black, vRulerRect.Right, drawY, vRulerRect.Right - 3, drawY)
            End Select
        Next
    End Sub
    
  • 第三步:可选交互优化
    • 需要鼠标定位辅助线:处理Panel的MouseMove事件,记录当前鼠标坐标,在Paint事件里额外在水平/垂直标尺对应位置绘制红色指示线即可
    • 需要支持页面缩放:所有绘图坐标、尺寸统一乘上缩放比例因子,标尺刻度值同步按比例换算
    • 需要可拖动页边距标记:在标尺对应边距位置绘制可拖动的小滑块,处理鼠标按下、移动、抬起事件,实时更新边距数值并重绘即可

内容的提问来源于stack exchange,提问作者Bluerose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 17:18:21