Scroll Bar 控件方案:创建可滚动的图形视口

本文介绍如何使用VB创建两个ActiveX Dll控件:SplitView用于实现窗体界面的分割视图;ScrollView用于创建可滚动的图形视口。通过代码重用和模块化设计提高开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由 Microsoft 所提出的部件对象模型 (COM) ,包括 Automation 和 ActiveX 规范。通过 ActiveX
部件技术可以把已创建的基于对象的部件组合起来,这些部件可以通过许多不同的工具来创建。应用"部
件软件开发"方法有代码重用、模块功能分明等许多好处。下面以创建独立的界面控制 ActiveX Dll 部
件为题,做进一步分析:

    以下两个 ActiveX Dll 部件均实现了"在部件内部响应事件",即:在类模块内引用带事件的对象,以
及在程序运行阶段动态添加控件(实现的技术细节可参阅《MSDN》)。
例2:在 Delphi 提供了 Splitter 控件,轻而易举就实现了窗体界面的分割视图,而在 VB 中要实现这一
    功能则要编写大量代码。
    可参阅 VB 6 的"树状视图列表视图拆分条"控件集或"VB 应用程序向导 --> 资源管理器样式"代码,
    现将其加工移植为 ActiveX Dll 部件:
        创建ActiveX Dll(命名为:EasyViews)工程,并在类模块(命名为:SplitView)
        添加如下代码:

Option Explicit
Dim mbMoving As Boolean

Const iError = 120
Const iErrorXY = 150
Const SplitterHW = 80

Dim LeftCtl As Control
Dim RightCtl As Control
Dim TopCtl As Control
Dim BottomCtl As Control

Dim WithEvents ImgSplitterH As Image
Dim WithEvents ImgSplitterV As Image

Dim PictureH As PictureBox
Dim PictureV As PictureBox

Dim WithEvents FormX As Form

Dim iMinWidth As Integer
Dim iMinHeight As Integer
Dim iLeftMargin As Integer
Dim iRightMargin As Integer
Dim iTopMargin As Integer
Dim iBottomMargin As Integer

Public Property Get LeftMargin() As Integer
       LeftMargin = iLeftMargin
End Property

Public Property Let LeftMargin(ByVal vNewValue As Integer)
       iLeftMargin = vNewValue
End Property

Public Property Get RightMargin() As Integer
       RightMargin = iRightMargin
End Property

Public Property Let RightMargin(ByVal vNewValue As Integer)
       iRightMargin = vNewValue
End Property

Public Property Get TopMargin() As Integer
       TopMargin = iTopMargin
End Property

Public Property Let TopMargin(ByVal vNewValue As Integer)
       iTopMargin = vNewValue
End Property

Public Property Get BottomMargin() As Integer
       BottomMargin = iBottomMargin
End Property
Public Property Let BottomMargin(ByVal vNewValue As Integer)
       iBottomMargin = vNewValue
End Property

Public Property Get MinWidth() As Integer
MinWidth = iMinWidth
End Property

Public Property Let MinWidth(ByVal vNewValue As Integer)
iMinWidth = vNewValue
End Property

Public Property Get MinHeight() As Integer
MinHeight = iMinHeight
End Property

Public Property Let MinHeight(ByVal vNewValue As Integer)
iMinHeight = vNewValue
End Property

Private Sub FormX_Load()
Dim temp As String

temp = "DynamicImageH"
On Error GoTo ErrorHandler
FormX.Controls.Add "VB.Image", temp, FormX
On Error GoTo 0
With FormX.Controls.Item(temp)
     .Visible = True
End With
Set ImgSplitterH = FormX.Controls.Item(temp)
ImgSplitterH.MousePointer = 7 'ccsizeEW

temp = "DynamicImageV"
On Error GoTo ErrorHandler
FormX.Controls.Add "VB.Image", temp, FormX
On Error GoTo 0
With FormX.Controls.Item(temp)
     .Visible = True
End With
Set ImgSplitterV = FormX.Controls.Item(temp)
ImgSplitterV.MousePointer = 9 'cc2sizeNS

temp = "DynamicPictureH"
On Error GoTo ErrorHandler
FormX.Controls.Add "VB.PictureBox", temp, FormX
On Error GoTo 0
Set PictureH = FormX.Controls.Item(temp)
PictureH.BorderStyle = 0
PictureH.BackColor = vbBlack

temp = "DynamicPictureV"
On Error GoTo ErrorHandler
FormX.Controls.Add "VB.PictureBox", temp, FormX
On Error GoTo 0

Set PictureV = FormX.Controls.Item(temp)

PictureV.BorderStyle = 0
PictureV.BackColor = vbBlack
LeftCtl.Move LeftMargin, TopMargin
ImgSplitterV.Move LeftCtl.Left + LeftCtl.Width, LeftCtl.Top, SplitterHW, LeftCtl.Height
RightCtl.Move ImgSplitterV.Left + SplitterHW, LeftCtl.Top
RightCtl.Height = LeftCtl.Height
ImgSplitterH.Move LeftCtl.Left, LeftCtl.Top + LeftCtl.Height, FormX.Width - LeftMargin - RightMargin, SplitterHW
BottomCtl.Move LeftCtl.Left, LeftCtl.Top + LeftCtl.Height + SplitterHW  'LeftCtl.Height

Exit Sub
ErrorHandler:
temp = temp & "X"
Resume
End Sub

Public Sub Create(LeftCtlX As Object, RightCtlX As Object, BottomCtlX As Object)
Set LeftCtl = LeftCtlX
Set RightCtl = RightCtlX
'Set TopCtl = TopCtlX
Set BottomCtl = BottomCtlX
Set FormX = LeftCtlX.Container
FormX_Load
End Sub

Private Sub FormX_Resize()
If FormX.WindowState <> vbMinimized Then
   If FormX.Width < LeftMargin + RightMargin + SplitterHW + MinWidth + LeftCtl.Width + iErrorXY Then
      FormX.Width = LeftMargin + RightMargin + SplitterHW + MinWidth + LeftCtl.Width + iErrorXY
   End If
   If FormX.Height < TopMargin + BottomMargin + SplitterHW + MinHeight + LeftCtl.Height + iErrorXY + iErrorXY + iErrorXY + 6 Then
      FormX.Height = TopMargin + BottomMargin + SplitterHW + MinHeight + LeftCtl.Height + iErrorXY + iErrorXY + iErrorXY + 6
   End If
   RightCtl.Width = FormX.Width - LeftCtl.Width - SplitterHW - LeftMargin - RightMargin - iErrorXY
   ImgSplitterH.Width = FormX.Width - LeftMargin - RightMargin - iErrorXY
   BottomCtl.Width = ImgSplitterH.Width
   BottomCtl.Height = FormX.Height - ImgSplitterH.Top - BottomMargin - SplitterHW - 405
End If
End Sub

Private Sub ImgSplitterH_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
With ImgSplitterH
     PictureH.Move .Left - 10, .Top, .Width + 30, .Height / 2
End With
PictureH.Visible = True
mbMoving = True
End Sub

Private Sub ImgSplitterH_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then
   If mbMoving Then
      If Y + ImgSplitterH.Top < LeftCtl.Top + MinHeight Then
         PictureH.Top = LeftCtl.Top + MinHeight
      ElseIf Y + ImgSplitterH.Top > FormX.Height - BottomMargin - SplitterHW - MinHeight - iErrorXY - iErrorXY - iErrorXY Then
         PictureH.Top = FormX.Height - BottomMargin - SplitterHW - MinHeight - iErrorXY - iErrorXY - iErrorXY
      Else
         PictureH.Top = Y + ImgSplitterH.Top
      End If
   End If
 End If
End Sub

Private Sub ImgSplitterH_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    LeftCtl.Height = PictureH.Top - LeftCtl.Top
    ImgSplitterV.Height = LeftCtl.Height
    RightCtl.Height = LeftCtl.Height
    ImgSplitterH.Top = PictureH.Top
    BottomCtl.Height = FormX.Height - ImgSplitterH.Top - BottomMargin - SplitterHW - 400 - 5
    BottomCtl.Top = PictureH.Top + SplitterHW
    PictureH.Visible = False
    mbMoving = False
End Sub

Private Sub ImgSplitterV_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
PictureV.Visible = True
With ImgSplitterV
     PictureV.Move .Left, .Top - 10, .Width / 2, .Height
End With
mbMoving = True
End Sub

Private Sub ImgSplitterV_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then
   If mbMoving Then
      If X + ImgSplitterV.Left < LeftCtl.Left + MinWidth Then
         PictureV.Left = LeftCtl.Left + MinWidth
      ElseIf X + ImgSplitterV.Left > FormX.Width - SplitterHW - RightMargin - MinWidth - iErrorXY Then
         PictureV.Left = FormX.Width - SplitterHW - RightMargin - MinWidth - iErrorXY
      Else
         PictureV.Left = X + ImgSplitterV.Left
      End If
   End If
   PictureV.Height = LeftCtl.Height
End If
End Sub

Private Sub ImgSplitterV_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
ImgSplitterV.Left = PictureV.Left
LeftCtl.Width = PictureV.Left - LeftCtl.Left
RightCtl.Width = FormX.Width - LeftCtl.Width - SplitterHW - LeftMargin - RightMargin - iErrorXY '- iError - 200
RightCtl.Left = PictureV.Left + SplitterHW
PictureV.Visible = False
mbMoving = False
End Sub

至此该部件创建完成。
    接下来创建标准工程,并在窗体上绘制任意三个控件,如: TreeView、ListView、DataGrid,并编写
如下代码测试 EasyViews 部件的类 SplitView:

Option Explicit
Dim x As New EasyViews.SplitView
Private Sub Form_Load()
'...
x.TopMargin = 500 ' Toolbar1.Height + 100
x.LeftMargin = 1000
x.RightMargin = 1000
x.BottomMargin = 500 'StatusBar1.Height
x.MinHeight = 1000
x.MinWidth = 1200
x.Create TreeView1, ListView1, DataGrid1
'...
End Sub


例1:使用过 Delphi 和 PB 的人应该知道,她们的 Form 和 Window 不需编程,即可实现滚动窗口。而在
    VB 中要实现滚动窗口则需要编写一些代码了,可参阅 MSDN:
    《Scroll Bar 控件方案:创建可滚动的图形视口》,现将其加工移植为 ActiveX Dll
    部件:
        创建 ActiveX Dll(命名为: EasyViews )工程,并在类模块 (命名为:ScrollView) 中添加如下
        代码:

Option Explicit
Dim Picture1 As PictureBox
Dim Picture2 As PictureBox
Dim Picture3 As PictureBox

Dim WithEvents HScroll1 As HScrollBar
Dim WithEvents VScroll1 As VScrollBar
Dim WithEvents FormX As Form

Dim iWidth As Integer
Dim iHeight As Integer
Dim iLeft As Integer
Dim iTop As Integer

Dim iLeftMargin As Integer
Dim iRightMargin As Integer
Dim iTopMargin As Integer
Dim iBottomMargin As Integer

Dim bAlignForm As Boolean

Const iErrorXY = 135
Const dXY = 60

Public Sub Create(PictureBox As Object, Optional bAlignFormX As Boolean = True)
Set Picture2 = PictureBox
Set FormX = PictureBox.Container
bAlignForm = bAlignFormX
FormX_Load
End Sub

Private Sub FormX_Load()
Dim temp As String

temp = "DynamicPicture1"
On Error GoTo ErrorHandler
FormX.Controls.Add "VB.PictureBox", temp, FormX
On Error GoTo 0
With FormX.Controls.Item(temp)
     .Visible = True
End With
Set Picture1 = FormX.Controls.Item(temp)

temp = "DynamicPicture3"
On Error GoTo ErrorHandler
FormX.Controls.Add "VB.PictureBox", temp, FormX
On Error GoTo 0
With FormX.Controls.Item(temp)
     .Visible = True
End With
Set Picture3 = FormX.Controls.Item(temp)

temp = "DynamicHScroll1"
On Error GoTo ErrorHandler
FormX.Controls.Add "VB.HScrollBar", temp ', FormX
On Error GoTo 0
With FormX.Controls.Item(temp)
     .Visible = True
End With
Set HScroll1 = FormX.Controls.Item(temp)

temp = "DynamicHScroll1"
On Error GoTo ErrorHandler
FormX.Controls.Add "VB.VScrollBar", temp ', FormX
With FormX.Controls.Item(temp)
     .Visible = True
End With
Set VScroll1 = FormX.Controls.Item(temp)

HScroll1.TabStop = False
VScroll1.TabStop = False
Set Picture1.Container = Picture3
Set HScroll1.Container = Picture3
Set VScroll1.Container = Picture3
Set Picture2.Container = Picture1
'Picture3.BorderStyle = 0
Picture1.BorderStyle = 0
Picture2.BorderStyle = 0
If Not bAlignForm Then
   Picture3.Move Left, Top, Width, Height
   HScroll1.Move 0, Picture3.Height - HScroll1.Height - dXY, Picture3.Width - VScroll1.Width - dXY
   VScroll1.Move Picture3.Width - VScroll1.Width - dXY, 0, VScroll1.Width, Picture3.Height - HScroll1.Height - dXY
   Picture1.Move 0, 0, Picture3.Width - VScroll1.Width - dXY, Picture3.Height - HScroll1.Height - dXY
   Picture2.Move 0, 0
   HScroll1.LargeChange = HScroll1.Max / 5
   VScroll1.LargeChange = VScroll1.Max / 5
   If Picture1.Height >= Picture2.Height Then
      HScroll1.Width = Picture3.Width - dXY
      Picture1.Width = Picture3.Width - dXY
   End If
   If Picture1.Width >= Picture2.Width Then
      VScroll1.Height = Picture3.Height - dXY
      Picture1.Height = Picture3.Height - dXY
   End If
   HScroll1.Max = Picture2.Width - Picture1.Width '+ 10 '+ dXY
   VScroll1.Max = Picture2.Height - Picture1.Height ' + 10 '+ dXY
   HScroll1.SmallChange = 100
   VScroll1.SmallChange = 100
   HScroll1.Visible = (Picture1.Width < Picture2.Width)
   VScroll1.Visible = (Picture1.Height < Picture2.Height)
End If
Exit Sub
ErrorHandler:
temp = temp & "X"
Resume
End Sub

Private Sub FormX_Resize()
On Error Resume Next
If bAlignForm Then
   Picture3.Move LeftMargin, TopMargin, FormX.Width - LeftMargin - RightMargin - iErrorXY, FormX.Height - TopMargin - BottomMargin - iErrorXY - iErrorXY - iErrorXY
   HScroll1.Move 0, Picture3.Height - HScroll1.Height - dXY, Picture3.Width - VScroll1.Width - dXY
   VScroll1.Move Picture3.Width - VScroll1.Width - dXY, 0, VScroll1.Width, Picture3.Height - HScroll1.Height - dXY
   Picture1.Move 0, 0, Picture3.Width - VScroll1.Width - dXY, Picture3.Height - HScroll1.Height - dXY
   Picture2.Move 0, 0
   HScroll1.LargeChange = HScroll1.Max / 5
   VScroll1.LargeChange = VScroll1.Max / 5
   If Picture1.Height >= Picture2.Height Then
      HScroll1.Width = Picture3.Width - dXY
      Picture1.Width = Picture3.Width - dXY
   End If
   If Picture1.Width >= Picture2.Width Then
      VScroll1.Height = Picture3.Height - dXY
      Picture1.Height = Picture3.Height - dXY
   End If
   HScroll1.Max = Picture2.Width - Picture1.Width ' + dXY
   VScroll1.Max = Picture2.Height - Picture1.Height ' + dXY
   HScroll1.SmallChange = 100
   VScroll1.SmallChange = 100
   HScroll1.Visible = (Picture1.Width < Picture2.Width)
   VScroll1.Visible = (Picture1.Height < Picture2.Height)
End If
End Sub

Private Sub HScroll1_Change()
Picture2.Left = -HScroll1.Value
End Sub

Private Sub VScroll1_Change()
Picture2.Top = -VScroll1.Value
End Sub

Public Property Get Width() As Integer
       Width = iWidth
End Property

Public Property Let Width(ByVal vNewValue As Integer)
       iWidth = vNewValue
End Property

Public Property Get Height() As Integer
       Height = iHeight
End Property

Public Property Let Height(ByVal vNewValue As Integer)
       iHeight = vNewValue
End Property

Public Property Get Left() As Integer
       Left = iLeft
End Property

Public Property Let Left(ByVal vNewValue As Integer)
       iLeft = vNewValue
End Property

Public Property Get Top() As Integer
       Top = iTop
End Property

Public Property Let Top(ByVal vNewValue As Integer)
       iTop = vNewValue
End Property

Public Property Get LeftMargin() As Integer
       LeftMargin = iLeftMargin
End Property

Public Property Let LeftMargin(ByVal vNewValue As Integer)
       iLeftMargin = vNewValue
End Property

Public Property Get RightMargin() As Integer
       RightMargin = iRightMargin
End Property

Public Property Let RightMargin(ByVal vNewValue As Integer)
       iRightMargin = vNewValue
End Property

Public Property Get TopMargin() As Integer
       TopMargin = iTopMargin
End Property

Public Property Let TopMargin(ByVal vNewValue As Integer)
       iTopMargin = vNewValue
End Property

Public Property Get BottomMargin() As Integer
       BottomMargin = iBottomMargin
End Property

Public Property Let BottomMargin(ByVal vNewValue As Integer)
       iBottomMargin = vNewValue
End Property

至此该部件创建完成。
    接下来创建标准工程,并在窗体上绘制一 PictureBox(Picture1) 控件,再绘制一定数量的各种控件
在该 PictureBox 控件内,并编写如下代码测试 EasyViews 部件的类 ScrollView :

Option Explicit
Dim x As New EasyViews.ScrollView
Dim y As New EasyViews.ScrollView
Private Sub Form_Load()
'...
x.Left = 1000
x.Top = 200
x.Height = 3000
x.Width = 4000
x.TopMargin = 3000
x.LeftMargin = 500
x.RightMargin = 500
x.BottomMargin = 600
x.Create Picture2 ', False

y.Left = 2000
y.Top = 300
y.Height = 2500
y.Width = 4000
'y.TopMargin = 1000
y.LeftMargin = 1000
y.RightMargin = 1000
y.BottomMargin = 4000
y.Create Picture1, False

'...
End Sub


    该方案使调用部件的主程序代码简洁明了,使实现界面控制的"代码部件"与实现其它功能的代码分离,
界限分明、一目了然。

 
<think>嗯,用户想通过CSS样式文件去除JavaFX中Textarea组件的滚动条。首先,我需要回忆一下JavaFX中控件的结构。TextArea本身内部包含了一个ScrollPane,而滚动条应该是ScrollPane的一部分。所以可能需要针对ScrollPane的滚动条进行样式设置。 接下来,JavaFX的CSS和普通网页的CSS有些不同,它使用类似于CSS的语法,但有些属性是特定的。例如,隐藏滚动条可能需要设置相关的轨道和箭头为透明,并且调整尺寸为零。比如,可以用`-fx-padding: 0;`来减少周围的空间,或者设置`-fx-opacity: 0;`来让滚动条不可见。 另外,可能需要使用`.scroll-pane > .viewport`来选择部分,确保内容区域正确显示。记得在CSS中,要针对ScrollPane的垂直和水平滚动条分别处理,可能需要用到`-fx-vertical-scrollbar`和`-fx-horizontal-scrollbar`的伪类选择器。不过,JavaFX的CSS文档中可能没有直接隐藏滚动条的属性,所以需要通过覆盖样式来实现,比如将滚动条的轨道和拇指的颜色设置为透明,或者调整滚动条的宽度为零。 然后,用户提供的参考内容中有提到CSS优先级,比如内联样式优先级高,但这里用户是要用外部样式表,所以需要确保样式正确应用。可能需要使用`.scroll-pane`类来定位到TextArea内部的ScrollPane,然后设置其滚动条不可见。例如: .scroll-pane .scroll-bar:vertical { -fx-opacity: 0; } 或者设置滚动条的大小为零: .scroll-pane .scroll-bar:vertical { -fx-pref-width: 0; } 不过,可能需要更精确的选择器,或者检查是否有其他子组件需要调整。此外,某些情况下可能需要设置`-fx-fit-to-height`和`-fx-fit-to-width`为true,让内容自动适应,避免出现滚动条。但TextArea默认可能不会这样,所以需要通过CSS来覆盖。 最后,测试这个CSS样式是否正确应用到TextArea的ScrollPane上,可能需要使用ScenicView工具来检查JavaFX控件的结构,确认选择器是否正确。如果滚动条仍然存在,可能需要更深入的样式调整,或者查看是否有其他默认样式覆盖了用户的设置。</think>### 如何通过CSS样式文件去除JavaFX中TextArea组件的滚动条? #### 步骤说明 1. **理解组件结构** JavaFX的`TextArea`内部嵌套了`ScrollPane`,滚动条属于`ScrollPane`的子组件。需要通过CSS选择器定位到滚动条相关节点[^2]。 2. **编写CSS规则** 在样式表中添加以下代码,隐藏垂直和水平滚动条: ```css /* 隐藏垂直滚动条 */ .scroll-pane .scroll-bar:vertical { -fx-pref-width: 0; -fx-opacity: 0; } /* 隐藏水平滚动条 */ .scroll-pane .scroll-bar:horizontal { -fx-pref-height: 0; -fx-opacity: 0; } ``` 3. **应用样式到TextArea** 将CSS文件加载到JavaFX场景中: ```java textArea.getStylesheets().add("path/to/your/styles.css"); ``` #### 关键原理 - 通过`-fx-pref-width`和`-fx-pref-height`将滚动条尺寸设为0,直接移除其占位空间。 - `-fx-opacity: 0`确保滚动条完全透明,避免残留觉元素。 - 使用`.scroll-pane`选择器精准定位`TextArea`内部的滚动容器[^2]。 #### 扩展优化 - **保留滚动功能**:若需隐藏滚动条但保留滚动能力(如触摸滑动),可仅设置透明度为0。 - **范围限制**:通过更精确的选择器(如`#specificTextArea .scroll-bar`)限制样式作用范围。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值