65.9K
CodeProject 正在变化。 阅读更多。
Home

iPhone 类控件 for .Net 第一部分:Rotator

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.69/5 (6投票s)

2014年7月22日

CPOL

7分钟阅读

viewsIcon

25801

downloadIcon

626

iPhone 选择旋转器作为 Winform .Net 控件

 

更新 2014年7月29日

 

Zip 文件包含一个 Visual Studio 项目家族,由三个项目组成。

  • IOSrotor
  • IOSswitch
  • 测试

开发系统:VisualStudio 2012
框架:.Net 4.5
语言:VB.Net

 

引言

你喜欢这些 iOS (iPhone/iPad) 控件吗?如果是,我采用了基本思路,并开发了一些相等的控件供 Winform 在 .Net 中使用。

这是两个控件中的第一个,另一个控件是

 

我知道有一篇关于带类似 WPF 控件的 Code Project Rotator 控件的文章,我也知道可以在 Winform 中使用 WPF 控件,但我不喜欢这种变通方法,因此我开发了这个漂亮的控件来扩展在 Winform 中向用户展示选择列表的可能性。

ISOrotor 能为你做什么?

A) 对用户而言。

  • 通过使用鼠标滚轮或键盘的向上/向下键在字符串或图像列表项中循环。
  • 通过单击选择器(控件的中间区域)来选择/选取某个项目。
  • 看到圆柱体向前或向后移动时循环。
  • 如果控件获得焦点,则看到边框。
  • 使用向上/向下键而不是鼠标滚轮。

B) 对开发者而言

  • 选择要使用的项目类型(字符串或图像),并预设 3-15 个要显示的字符串或图像。
  • 为每个图像指定唯一的名称作为标识符。
  • 更改项目的前景色和对齐方式。
  • 更改选择器(中间可点击的选取区域)的字体和前景色。
  • 更改循环圆柱体的颜色。
  • 决定选择器区域是否用半透明绿色高亮显示。
  • 决定选择器区域是否有边框。

示例请参见上图。

基本思路

控件的基础是一个 UserControl,它包含 3 个透明面板。Panel A 停靠在顶部,Panel C 停靠在底部,Panel B(选择器)在中间。

每个面板包含一个 Label 和一个 PictureBox 控件。根据属性 ItemType 的值,Label 或 PictureBox 可见。

为了模仿预定义项目(字符串或图像)的循环,我们将它们向上或向下移动到上面/下面面板的下一个/上一个 Label/PictureBox。

开始时,预定义项目列表的第一个项目显示在中间区域(在选择器中)。

项目以无限链的形式呈现。

使用代码

使用的图像可能具有透明的 Alpha 通道,尺寸不小于 150x99 像素。之所以使用这么大的尺寸,是为了即使在控件被放大到更大尺寸时也能显示出美观的圆柱体图片。标准尺寸为 150 x 99 像素。

控件至少需要 3 个项目,最多 15 个项目,这在父窗体的 Load 事件中完成(请参见下面的描述)。自定义属性可以通过代码或直接在控件的属性网格中设置。

安装

将控件的 DLL 添加到 VisualStudio 工具箱。它由图标 表示。

  1. 将控件从工具箱拖到窗体上。
  2. 设置项目(图像和/或字符串)- Form_load 事件。
  3. 通过代码或在属性网格中设置属性 - Form_load 事件。
  4. 在父窗体中创建 Sub SelectorClicked(..) 事件。

循环的魔力

控件最重要的工作是以正确的顺序向上或向下循环项目并为循环的圆柱体制作动画。

为了管理循环,我构建了一套特殊的类。非常感谢我的朋友 Christoph Knorr,他是一名计算机科学专业的学生,他为我做了这项出色的工作。

类 clsListitem

此类创建一个新的对象ListelementListelement 保存从一个 Label/PictureBox 移动到下一个/上一个的值。Listelement DoubleChainedList 类使用。set 函数用于将值传输到 Label/PictureBox。

Public Class Listelement
    'Public value As Integer 'eigentliche Daten
    Public value As Object
    Public nextElem, prevElem As Listelement 'Zeiger auf nächstes und vorheriges Element
    ' ## waren vorher private´, müsen aber public sein, da sonst von aussen nicht darauzf zugegriffen werden kann

    Public Sub New(ByVal value As Object) 'Konstruktor
        Me.value = value
        nextElem = Nothing
        prevElem = Nothing
    End Sub

    Public Sub setNextElem(ByVal nextElem As Listelement)
        Me.nextElem = nextElem
    End Sub

    Public Sub setPrevElem(ByVal prevElem As Listelement)
        Me.prevElem = prevElem
    End Sub

    Public Function getNextElem() As Listelement
        Return nextElem
    End Function

    Public Function getPrevElem() As Listelement
        Return Me.prevElem
    End Function

    Public Function getValue() As Object 'Integer
        Return value
    End Function
End Class

类 DoubleChainedList

此类管理正确的向前或向后移动。它移动 Listelements 并提供将新 Listelements 添加到内部元素堆栈的可能性。该类提供了scrollUp scrollDown 函数,用于在控件的移动事件(鼠标滚轮滚动/ keyDown 事件)中使用。

Public Class DoubleChainedList

    Private startElem As New Listelement(0)
    Private secondElem As New Listelement(1)
    Private thirdElem As New Listelement(2)

    Public Sub New(ByVal firstvalue As Object, ByVal secondvalue As Object, ByVal thirdvalue As Object)
        startElem.setNextElem(secondElem)
        startElem.setPrevElem(thirdElem)
        startElem.value = firstvalue
        secondElem.setNextElem(thirdElem)
        secondElem.setPrevElem(startElem)
        secondElem.value = secondvalue
        thirdElem.setPrevElem(secondElem)
        thirdElem.setNextElem(startElem)
        thirdElem.value = thirdvalue
    End Sub

    Public Sub add(ByVal value As Object) ' wird immer vor dem aktuell ersten Element eingefügt
        Try
            Cursor.Current = Cursors.WaitCursor
            Dim newElem, pointerElem As Listelement
            newElem = New Listelement(value)
            pointerElem = startElem.getPrevElem()
            pointerElem.setNextElem(newElem)
            newElem.setNextElem(startElem)
            newElem.setPrevElem(pointerElem)
            startElem.setPrevElem(newElem)
        Catch ex As Exception
            Cursor.Current = Cursors.Default
            MsgBox(ex.Message, MessageBoxIcon.Exclamation, Application.ProductName)
        Finally
            Cursor.Current = Cursors.Default
        End Try

    End Sub

    Public Function getFirstElem() As Listelement
        Return startElem
    End Function

    Public Function getSecondElem() As Listelement
        Return secondElem
    End Function

    Public Function getThirdElem() As Listelement
        Return thirdElem
    End Function

    Public Sub scrollUp()
        startElem = secondElem
        secondElem = thirdElem
        thirdElem = thirdElem.nextElem
    End Sub

    Public Sub scrollDown()
        thirdElem = secondElem
        secondElem = startElem
        startElem = startElem.prevElem
    End Sub
End Class

类 IOSrotor

这是 UserControl 的类。为了便于阅读,它按区域划分。现在让我们看一下这些区域。

类头 私有变量和自定义事件区域

Imports System.Windows.Forms
Imports System.ComponentModel
Imports System.Threading.Thread
Imports System.Drawing.Drawing2D

<ToolboxBitmap(GetType(IOSrotor))> Public Class IOSrotor

#Region " Declaration"

    ' ## the event to return the clicked result
    Public Event SelectorClicked(ByVal Result As Object)

    ' ## variables for the properties
    Public Enum enuItemType As Integer
        Text
        Picture
    End Enum
    Public Enum enuAlignment As Integer
        Left
        Center
        Right
    End Enum
    Public Enum enuSkin As Integer
        Silver
        Red
        Yellow
        Green
        Blue
    End Enum

    Private _ItemType As Integer = enuItemType.Text
    Private _ItemTextAlign As Integer = enuAlignment.Center
    Private _Skin As Integer = enuSkin.Silver
    Private _SelectorBorder As Boolean = False
    Private _SelectorFont As Font
    Private _SelectorForeColor As Color
    Private _INIReg As Boolean = False

    ' ## the arrays and variables to hold the selectable items
    Public ItemText(14) As String
    Public Image(14) As Image
    Public ImageName(14) As String

    ' ## the variables to manage the register changing (scrolling)
    Private imageA, imageB, imageC As Image
    Public Register As DoubleChainedList
    Private RegisterItem As Listelement

    Private intBorderThickness As Integer = 1
    Private colBorderColor As Color = Color.Transparent

#End Region

类自定义属性区域

注意属性Name 与属性网格中显示的名称(DisplayName)之间的区别。

#Region "custom Properties"

    <Category("Items"), DisplayName("Initialize"), _
        Description("First populate Images/ItemText Arrays!"),
    Browsable(False)> Public Property IniRegister As Boolean
        Get
            Return _INIReg
        End Get
        Set(value As Boolean)
            If value Then
                If ItemType = enuItemType.Picture Then
                    ' ## check how many pictures are populated
                    Dim temp As Integer = 0
                    For y0 As Integer = 0 To UBound(Image)
                        If Not IsNothing(Image(y0)) Then
                            temp += 1
                        Else
                            Exit For
                        End If
                    Next
                    If temp >= 3 Then ' minimum must be 3
                        Register = Nothing ' clear
                        Register = New DoubleChainedList(Image(0), Image(1), _
                            Image(2))
                        For y1 As Integer = 3 To temp - 1
                            If Not IsNothing(Image(y1)) Then Register.add(Image(y1))
                        Next
                    End If
                        ' ## reset value
                        _INIReg = False
                    ElseIf ItemType = enuItemType.Text Then
                        ' ## check how many pictures are populated
                        Dim temp As Integer = 0
                    For x As Integer = 0 To UBound(ItemText)
                        If ItemText(x) <> "" Then
                            temp += 1
                        Else
                            Exit For
                        End If
                    Next
                        If temp >= 3 Then ' minimum must be 3
                            Register = Nothing ' clear
                            Register = New DoubleChainedList(ItemText(0), _
                                ItemText(1), ItemText(2))
                        For y2 As Integer = 3 To temp - 1
                            If ItemText(y2) <> "" Then _
                                Register.add(ItemText(y2))
                        Next
                        End If
                        ' ## reset value
                        _INIReg = False
                    End If
                ' ## go to first register position
                    moveForward()
                End If
        End Set
    End Property

    <Category("Items"), DisplayName("Item Type"), _
        Description("Type of Items.")> Public Property ItemType As enuItemType
        Get
            Return _ItemType
        End Get
        Set(value As enuItemType)
            _ItemType = value
            If value = enuItemType.Text Then
                picA.Dock = DockStyle.None : picB.Dock = DockStyle.None
                picA.Dock = DockStyle.None
                picB.Visible = False : picA.Visible = False
                picC.Visible = False
                lblA.Dock = DockStyle.Fill : lblB.Dock = DockStyle.Fill
                lblC.Dock = DockStyle.Fill
                lblB.Visible = True : lblA.Visible = True
                lblC.Visible = True

            Else
                lblA.Dock = DockStyle.None : lblB.Dock = DockStyle.None
                lblC.Dock = DockStyle.None
                lblB.Visible = False : lblA.Visible = False
                lblC.Visible = False
                picA.Dock = DockStyle.Fill : picB.Dock = DockStyle.Fill
                picA.Dock = DockStyle.Fill
                picB.Visible = True : picA.Visible = True
                picC.Visible = True
            End If
        End Set
    End Property

    <Category("Items"), DisplayName("Item Alignment"), _
        Description("Aligment for Items type of Text.")> Public Property _
        ItemTextAlign As enuAlignment
        Get
            Return _ItemTextAlign
        End Get
        Set(value As enuAlignment)
            ' ## change alignment only if ItemType is Text
            If ItemType = enuItemType.Text Then
                _ItemTextAlign = value
                Select Case value
                    Case enuAlignment.Center
                        lblB.TextAlign = ContentAlignment.MiddleCenter
                        lblA.TextAlign = ContentAlignment.MiddleCenter
                        lblC.TextAlign = ContentAlignment.MiddleCenter
                    Case enuAlignment.Left
                        lblB.TextAlign = ContentAlignment.MiddleLeft
                        lblA.TextAlign = ContentAlignment.MiddleLeft
                        lblC.TextAlign = ContentAlignment.MiddleLeft
                    Case enuAlignment.Right
                        lblB.TextAlign = ContentAlignment.MiddleRight
                        lblA.TextAlign = ContentAlignment.MiddleRight
                        lblC.TextAlign = ContentAlignment.MiddleRight
                End Select
            End If
        End Set
    End Property

    <Category("Selector"), DisplayName("Selector Highlighted"), _
        Description("Show/hide transparent green Selector")> Public Property _
        SelectorGreen As Boolean
        Get
            Return _SelectorBorder
        End Get
        Set(value As Boolean)
            _SelectorBorder = value
            If value Then
                PanelB.BackgroundImage = My.Resources.SelectorBack
            Else
                PanelB.BackgroundImage = Nothing
            End If
        End Set
    End Property

    <Category("Selector"), DisplayName("Selector Font"), _
        Description("The Font of the Selector.")> Public Property SelectorFont _
        As Font
        Get
            Return _SelectorFont
        End Get
        Set(value As Font)
            _SelectorFont = value
            lblB.Font = value
        End Set
    End Property

    <Category("Selector"), DisplayName("Selector Textcolor"), _
        Description("Textcolor of the Selector.")> Public Property _
        SelectorForeColor As Color
        Get
            Return _SelectorForeColor
        End Get
        Set(value As Color)
            _SelectorForeColor = value
            lblB.ForeColor = value
        End Set
    End Property

    <Category("Skin"), DisplayName("Skin"), _
        Description("The controls skin.")> Public Property Skin As enuSkin
        Get
            Return _Skin
        End Get
        Set(value As enuSkin)
            _Skin = value
            My.Settings.Skin = value
            My.Settings.Save()
            Select Case value
                Case enuSkin.Blue
                    Me.BackgroundImage = My.Resources.blueB
                    imageA = My.Resources.bluebA
                    imageB = My.Resources.bluebA
                    imageC = My.Resources.blueB
                Case enuSkin.Green
                    Me.BackgroundImage = My.Resources.greenB
                    imageA = My.Resources.greenA
                    imageB = My.Resources.greenB
                    imageC = My.Resources.greenC
                Case enuSkin.Red
                    Me.BackgroundImage = My.Resources.redB
                    imageA = My.Resources.redA
                    imageB = My.Resources.redB
                    imageC = My.Resources.redC
                Case enuSkin.Yellow
                    Me.BackgroundImage = My.Resources.yellowB
                    imageA = My.Resources.yellowA
                    imageB = My.Resources.yellowB
                    imageC = My.Resources.yellowC
                Case enuSkin.Silver
                    Me.BackgroundImage = My.Resources.silverB
                    imageA = My.Resources.silverA
                    imageB = My.Resources.silverB
                    imageC = My.Resources.silverC
            End Select
        End Set
    End Property

    <Category("Info"), DisplayName("Version"), _
        Description("The controls version information")> Public ReadOnly _
        Property Version As Object
        Get
            Return My.Application.Info.Version
        End Get
    End Property
#End Region

类 UserControl 事件区域

首先,我们使用标准的控件属性Font changed ForeColor changed 将给定属性值传输到子项的相同值。

有一个大问题需要解决。面板及其子控件覆盖了 UserControl 的整个区域。因此,获得正确的焦点存在问题,这导致只有一个控件在工作,如果同一窗体中有多个控件实例。

解决方案的第一部分是通过在控件获得焦点时在其周围绘制边框,并在失去焦点时不显示边框来实现的。通过这种方式,用户可以识别哪个旋转器控件当前具有焦点。我们在Got Fous Lost Focus 事件中调用边框绘制。请注意Invalidate 命令会强制完全重绘,此命令比使用refresh 命令效果更好。边框的绘制在Paint event 中完成。

#Region "control events"
    ' ## if the controls font changed transmit new font value to child controls
    Private Sub tumbler_FontChanged(sender As Object, e As EventArgs) _
        Handles Me.FontChanged
        ' ## ini the font  except lblB as the independend selector
        lblB.Font = Me.Font : lblC.Font = Me.Font
    End Sub

    ' ## if the controls ForeColor changed transmit the new color to the child controls
    Private Sub tumbler_ForeColorChanged(sender As Object, e As EventArgs) _
        Handles Me.ForeColorChanged
        ' ## ini the forecolor except lblB as the independend selector
        lblB.ForeColor = Me.ForeColor : lblC.ForeColor = Me.ForeColor
    End Sub

    ' ## if focus is on draw a thicker border
    Private Sub IOSrotor_GotFocus(sender As Object, e As EventArgs) Handles Me.GotFocus
        colBorderColor = Color.Black
        intBorderThickness = 2
        Invalidate()
    End Sub

    ' ## if fous is lost draw the standard border
    Private Sub IOSrotor_LostFocus(sender As Object, e As EventArgs) Handles Me.LostFocus
        colBorderColor = Color.Transparent
        intBorderThickness = 1
        Invalidate()
    End Sub

    ' ## if Key Down or Key Up is pressed do the same as using the mouse wheel
    Private Sub tumbler_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
        If e.KeyCode = Keys.Oemplus Then
            moveForward()
        ElseIf e.KeyCode = Keys.OemMinus Then
            moveBackward()
        End If
    End Sub

    ' ## inbitialize values if control is loaded
    Private Sub tumbler_Load(sender As Object, e As EventArgs) Handles _
        Me.Load
        ' ## ini fonts and forecolor except lblB as the independend selector
        lblB.Font = Me.Font : lblC.Font = Me.Font
        lblB.ForeColor = Me.ForeColor : lblC.ForeColor = Me.ForeColor
        SelectorForeColor = Me.ForeColor : SelectorFont = Me.Font
        ' ## ini backcolor
        Me.BackColor = Me.ParentForm.BackColor
        Me.BorderStyle = Windows.Forms.BorderStyle.None
        Invalidate()
    End Sub

    ' ## on mouse wheel turn move the controls selectable items in then
    ' ## same direction up/downward
    Private Sub tumbler_MouseWheel(sender As Object, e As MouseEventArgs) Handles Me.MouseWheel
        Try
            Cursor.Current = Cursors.WaitCursor
            ' ## move down / foreward)
            If e.Delta < 0 Then
                moveForward()
            Else ' back
                moveBackward()
            End If
        Catch ex As Exception
            Cursor.Current = Cursors.Default
            MsgBox(ex.Message, MessageBoxIcon.Exclamation, _
                Application.ProductName)
        Finally
            Cursor.Current = Cursors.Default
        End Try
    End Sub

    ' ## paint event to drwa the border
    Private Sub IOSrotor_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
        ControlPaint.DrawBorder(e.Graphics, Me.ClientRectangle, _
                colBorderColor, intBorderThickness, ButtonBorderStyle.Solid, _
                colBorderColor, intBorderThickness, ButtonBorderStyle.Solid, _
                colBorderColor, intBorderThickness, ButtonBorderStyle.Solid, _
                colBorderColor, intBorderThickness, ButtonBorderStyle.Solid)
    End Sub

    ' ## if control is resized  make sure that the  panels are
    ' ## covering the controls area correctly
    Private Sub tumbler_Resize(sender As Object, e As EventArgs) Handles _
        Me.Resize
        ' ## set height of panels
        Dim intHeight As Integer = Me.Height / 3
        PanelA.Height = intHeight
        PanelB.Height = Me.Height - PanelA.Height - PanelC.Height
        PanelC.Height = intHeight
        ' ## redraw
        Invalidate()
    End Sub

#End Region

解决方案的第二部分是通过确保控件获得焦点来实现的。当用户单击子控件之一时,我们必须激活它的焦点。

#Region "other control events"
    ' ## this is used to grab/set the focus on this control
    Private Sub lblA_Click(sender As Object, e As EventArgs) Handles lblA.Click, lblC.Click, picA.Click, picB.Click
        Me.Focus()
    End Sub
#End Region

为了传输所选项目的相关信息,我们使用中间Panel B 中的子控件的单击事件和自定义事件SelectorClicked

    Public Event SelectorClicked(ByVal Result As Object)
  • Result 包含选定的字符串或选定图像的名称。
#Region "selector events"

    ' ## if lblB/picB is clicked (the Selector) than fire
    ' ## event SelectorCLicked and report selected item info
    Protected Sub Selector_Click(sender As Object, e As EventArgs) Handles _
        picB.Click, lblB.Click
        Try
            ' ## set fous on me
            Me.Focus()
            ' ## return selected value
            If ItemType = enuItemType.Picture Then
                ' lookup for the pictures name
                For x = 0 To Image.Length
                    If Image(x) Is picB.Image Then
                        ' Report selected item/image and its name
                        RaiseEvent SelectorClicked(ImageName(x))
                        Exit Sub
                    End If
                Next
            ElseIf ItemType = enuItemType.Text Then
                ' ## report selected item text
                RaiseEvent SelectorClicked(lblB.Text)
            End If
        Catch ex As Exception
            Cursor.Current = Cursors.Default
            MsgBox(ex.Message, MessageBoxIcon.Exclamation, _
                Application.ProductName)
        End Try
    End Sub

当鼠标指针悬停在中间面板(选择器)上方时,我们希望标准光标更改为Hand cursor

    Private Sub lblB_MouseHover(sender As Object, e As EventArgs) Handles _
        lblB.MouseHover, picB.MouseHover
        ' ## show cursor.hand over selector
        lblB.Cursor = Cursors.Hand
        picB.Cursor = Cursors.Hand
    End Sub

最后,我们需要两个私有函数来向前或向后移动。

除了不同的移动方向外,这些函数是相同的。我们首先切换背景图像来为圆柱体循环制作动画。为了看到每个图像,我们在进程中等待 250 毫秒,然后加载下一个。由于 Vb.Net 中没有直接的 sleep 或 wait 命令,我们使用适当的Thread 命令来替代它。为了显示 Label/PictureBox 的正确内容,我们使用我们DoubleChainedList 类的get.Elem 函数。

#Region "private Functions"

    ' ## animate a forwar turnd and rearrange the registers
    ' ## (labels/pictureboxes)
    Sub moveForward()
        Try
            ' ## animate
            Me.BackgroundImage = imageC : Me.Refresh()
            Threading.Thread.Sleep(250) ' wait to show animation
            Me.BackgroundImage = imageB : Me.Refresh()
            ' ## set slots
            Register.scrollDown()
            If ItemType = enuItemType.Picture Then
                picA.Image = Register.getFirstElem.value
                picB.Image = Register.getSecondElem.value
                picC.Image = Register.getThirdElem.value
            ElseIf ItemType = enuItemType.Text Then
                lblA.Text = Register.getFirstElem.value
                lblB.Text = Register.getSecondElem.value
                lblC.Text = Register.getThirdElem.value
            End If
        Catch ex As Exception
            Cursor.Current = Cursors.Default
            MsgBox(ex.Message, MessageBoxIcon.Exclamation, _
                Application.ProductName)
        Finally
            ' ## control repaint
            Me.Refresh()
        End Try
    End Sub

    ' ## animate a backward turn and rearrange the registers
    ' ## (labels/pictureboxes)
    Sub moveBackward()
        Try
            ' ## animate
            Me.BackgroundImage = imageA : Me.Refresh()
            Threading.Thread.Sleep(250) ' wait to show animation
            Me.BackgroundImage = imageB : Me.Refresh()
            ' ## set slots
            Register.scrollUp()
            If ItemType = enuItemType.Picture Then
                picA.Image = Register.getFirstElem.value
                picB.Image = Register.getSecondElem.value
                picC.Image = Register.getThirdElem.value
            ElseIf ItemType = enuItemType.Text Then
                lblA.Text = Register.getFirstElem.value
                lblB.Text = Register.getSecondElem.value
                lblC.Text = Register.getThirdElem.value
            End If
        Catch ex As Exception
            Cursor.Current = Cursors.Default
            MsgBox(ex.Message, MessageBoxIcon.Exclamation, _
                Application.ProductName)
        Finally
            ' ## control repaint
            Me.Refresh()
        End Try
    End Sub
#End Region

 

设置父窗体

为了初始化控件,我们使用 Load 事件。

  1. 我们将项目字符串和/或图像设置到内部项目数组ItemText() /Image()
  2. 我们选择要显示的ItemType
  3. 我们将IniReg 属性值设置为true 以强制将数组中的项目添加到类DoubleChainedList 使用的内部堆栈中。
    重要!在设置好项目字符串/图像数组之前,请勿使用此属性。如果您想先清除堆栈,请更改字符串/图像数组值,然后再次使用此属性。
  4. 我们设置了剩余的自定义属性(请记住,您也可以直接在属性网格中进行设置)。
 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Try
            Cursor.Current = Cursors.WaitCursor
            ' ## initialize 1st IOSrotor control
            With IoSrotor1
                ' ## set string values
                .ItemText(0) = "Speed"
                .ItemText(1) = "Length"
                .ItemText(2) = "Weight"
                .ItemText(3) = "Volume"
                .ItemText(4) = "Temperature"
                ' ## choose item type to be displayed
                .ItemType = TechDOCiosRotor.IOSrotor.enuItemType.Text
                ' ## ini the internal register with above the values
                ' ##
                .IniRegister = True
                ' ## choose skin
                .Skin = TechDOCiosRotor.IOSrotor.enuSkin.Silver
                ' ## choose text alignment
                .ItemTextAlign = TechDOCiosRotor.IOSrotor.enuAlignment.Center

                ' ## chosse selector paramters
                .SelectorForeColor = Color.Black
                .SelectorGreen = True
                .SelectorFont = New Font(IoSrotor1.Font.FontFamily, IoSrotor1.Font.Size, FontStyle.Bold)
            End With
            ' ## initialize 2nd IOSrotor control
            With IoSrotor3
                ' ## set image values
                .Image(0) = My.Resources.apple : .ImageName(0) = "Apple"
                .Image(1) = My.Resources.Banana : .ImageName(0) = "Banana"
                .Image(2) = My.Resources.pear : .ImageName(0) = "Pear"
                ' ## choose item type to be displayed
                .ItemType = TechDOCiosRotor.IOSrotor.enuItemType.Picture
                ' ## ini the internal register with above the values
                ' ##
                .IniRegister = True
                ' ## choose skin
                .Skin = TechDOCiosRotor.IOSrotor.enuSkin.Silver
                ' ## choose text alignment
                .ItemTextAlign = TechDOCiosRotor.IOSrotor.enuAlignment.Center

                ' ## chosse selector paramters
                .SelectorForeColor = Color.Black
                .SelectorGreen = True
                .SelectorFont = New Font(IoSrotor1.Font.FontFamily, IoSrotor1.Font.Size, FontStyle.Bold)
            End With
        Catch ex As Exception
            Cursor.Current = Cursors.Default
            MsgBox(ex.Message, MessageBoxIcon.Exclamation, Application.ProductName)
        Finally
            Cursor.Current = Cursors.Default
        End Try

    End Sub

当用户单击中间项(选择器)时,会触发自定义事件SelectorClicked。我们可以在我们的父窗体代码中使用此事件。

 ' ## user clicks on the selector of the rotor control
    Private Sub IOSrotor1_SelectorClicked(Result As Object) Handles IoSrotor1.SelectorClicked, IOSrotor3.SelectorClicked
        Try
            Cursor.Current = Cursors.WaitCursor
            If IoSrotor1.ItemType = TechDOCiosRotor.IOSrotor.enuItemType.Picture Then
                Select Case Name
                    Case "Apple"

                End Select
            ElseIf IoSrotor1.ItemType = TechDOCiosRotor.IOSrotor.enuItemType.Text Then
                Select Case Result
                    Case "Speed"

                End Select
            End If
        Catch ex As Exception
            Cursor.Current = Cursors.Default
            MsgBox(ex.Message, MessageBoxIcon.Exclamation, Application.ProductName)
        Finally
            Cursor.Current = Cursors.Default
        End Try
    End Sub

 

关注点

信不信由你,开发正确的移动过程花了我至少一周的时间。也许我太笨了,记不起我以前关于寄存器移位(汇编)的知识了,我放弃了并问了我的朋友。他在 3 天内就找到了解决方案 - 干得好!

下一个问题是背景圆柱体图像的动画。在我最初的解决方案中,我使用了一个 GIF 动画。这是不可能的,因为我遇到了透明背景的覆盖面板及其子控件的问题,因此我决定通过在向上或向下移动之间切换图像来管理动画。

历史

更新 2014年7月29日

  • 修复了一些错误。
  • 添加了焦点时显示/隐藏边框的功能。
  • 更改了 Selector_Clicked 事件,现在只有一个参数 Result。
  • 更改了动画序列。
  • 更改了测试项目窗体中的 missing handles 命令。
  • 解决了多个实例在同一个窗体上的焦点问题。
  • 将其他 IOS 类控件 IOSswitch 添加到项目家族。
© . All rights reserved.