Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

iPhone like controls for .Net Part 1: Rotator

0.00/5 (No votes)
13 Aug 2014 1  
iPhone selection rotator as Winform .Net control

 

UPDATE 29.7.2014

 

The Zip File includes a Visual Studio Project Family consisting of three Projects.

  • IOSrotor
  • IOSswitch
  • Test

Developmentsystem: VisualStudio 2012
Framework: .Net 4.5
Language: VB.Net

 

Introduction

Do you like this ios (iphone/ipad) controls? If yes I took the basic idea and developed some equal controls for the use with Winform in .Net.

This is the 1st control of two the other control is:

 

I know that there is an article for the rotator control with a simmillar control for WPF in code project and I know too that it is possible to use WPF controls inside a Winform  but I do not like this workaround and therefor I developed this nice control to extend the possibilities to present the user a selection list in a Winform.

What can ISOrotor do for you?

A) For the User.

  • Cycle through a list items of Strings or Images by using the Mouse wheel or the Up/Down Keys of the keyboard.
  • Choose/select on of the items by clicking on the Selector (this is the middle Area of the control).
  • See the cylinder cycling if moving forward or backward.
  • See a border if the control is focused.
  • Use key Up/Down instead of Mouse wheel.

B) For the Developer

  • Choose the item type to be used (String or Image) and preset 3-15 Strings or Images to be displayed.
  • Give each Image a unique name as Identifier.
  • Change the Font  Forecolor and Alignment of the items.
  • Change the Font and Forecolor of the Selector (the clickable selecting Area in the middle).
  • Change the color of the cycling cylinder.
  • Decide if the Selector area is highlighted with a semitransparent green color.
  • Decide if the Selector area may have a Border or not.

For examples see pictures above.

The Basic Idea

The controls base is a usercontrol that contains 3 transparent Panels . Panel A ist docked to the top Panel C is docked to the Bottom and Panel B (the Selector) is in the middle.

Each panel contains a label and a picturebox control inside. Due to the value of the property ItemType the label or the picturebox is visible.

To imitate the cycling of the predefined items (Strings or Images) we move them up or down from one label/picturebox of a panel to the next/previous label/picturebox of the panel above/below.

At the beginning the first item of the predefined item list is shown in the middle Area (in the Selector).

The items are presented as an endless chain.

Using the code

The images you use may have an transparent Aplha Chanel and a size not less 150x99 pixel. This big size is used to become a good looking cylinder picture even if the control is resized to a bigger dimension. The standard dimension is 150 x 99 pixel.

The control must be populated with 3 items in the minimum and 15 items in the maximum this is done in the Load event of the parent form (see description below). The custom properties may be set by code or direct in the controls property grid.

Installing

Add the controls DLL to the VisualStudio Toolbox. It is represented by the icon .

  1. Drag the control from the toolbox onto the Form.
  2. Set the items (images and/or strings) - Form_load event.
  3. Set the properties by code or in the property grid - Form_load event.
  4. Create Sub SelectorClicked(..) event in the parent form.

The cycling magic

The most important work of the control is to cycle the items in the correct sequence upward or downward and to animate the cycling cylinder.

To manage the cycling I build a special set of classes. Thank you very much for my friend Christoph Knorr who is a student of informatics and who did this excellent work for me.

Class clsListitem

This class creates a new object the Listelement. The Listelement holds the value moving from one label/picturebox to the next/previous. The Listelement is used by the class DoubleChainedList. The set functions are used to transfer the value to the labels/pictureboxes.

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

Class DoubleChainedList

This class manages the correct forward or backward movement. It moves the Listelements and gives the possibility to add  new Listelements into the internal element stack. The class provides the functions scrollUp and scrollDown to be used in the movement event of the control (Mous wheel scrolls/ keyDown event).

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

Class IOSrotor

This is the class of the usercontrol. For better reading it is devided by regions. Let's go through the regions now.

Class Header Privat Variable and Custom Event Area:

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

Class Region of custom properties:

Notice the difference between the property Name and the name shown in the property grid (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

Class region of usercontrol events:

First we use the standard control properties Font changed and ForeColor changed to transfer the given property values to the same values of the child items.

There is one big problem to solve. The panels and its child controls are covering the complete area of the usercontrol. Therefor there is a problem to become the correct focus this leads to the circumstance that only one control is working if multiple instances  of the control are on the same form.

The first part of the solution is done by drawing a boarder around the control if it has the focus and hiding the border if not. Due to this the user is able to recognize which rotor control has the current focus. We  call the border drawing in the Got Fous and Lost Focus events. Notice command Invalidate to force a complete redrawing using this command does a better job than using the refresh command. The drawing of the border is done in the 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

The scond part of the solution is realized by making sure the control has the focus. We have to activate its focus if the user clicks on one of the child controls.

#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

To transfer the information of the selected item we use the click event of the child control in the middle Panel B and the custom event SelectorClicked.

    Public Event SelectorClicked(ByVal Result As Object)
  • Result contains the selected string or the name of the selected image.
#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

We want that the standard cursor changes to the Hand cursor if the Mouse pointer is hovering above the middle Panel (Selector).

    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

At least we need two private functions to move forward or backward.

Except the different movement directions this functions ar equal. We start with switching the background image to animate the cylinder cycling. To see each image we hold on the process 250ms until loading the next one. Due to there is no direct sleep or wait command in Vb.Net we substitute this command by using the appropriated Thread command. To show the correct contents of  the labels/pictureboxes we use the functions get.Elem of our class DoubleChainedList.

#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

 

Setting up the parent Form

to initialize the control we use the load event.

  1. We set the item strings and or the images to the internal item arrays ItemText() / Image().
  2. We choose the ItemType to be displayed.
  3. We set the property value of IniReg to true to force the adding of the items from the arrays to the internal stack used and build by the class DoubleChainedList.
    Important! Do not use this property before you setup the item strings/images arrays. If you like to clear the stack first change the string/image Array values and than use this property again .
  4. We set the rest of the custom properties (remember you can do this direct in the property grid as well).
 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

If the user clicks on the middle item (Selector) the custom event SelectorClicked is fired. We can use this event in our parent forms code.

 ' ## 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

 

Points of Interest

Belive it or not to develop the correct movement procedures cost me at least one week. May be I am to stupid and not remembering my old Knowledge of Register Shifting (Assembler) I give up and asked my friend. He got the solution in 3 Days - well done!

Next problem is the animation of the cylinder image in the background. In my first solution I use a animated GIF. This was not possible because I got in trouble with the transparent backgrounds of the overlaying panels and theire child controls, Therefor I decided to manage the animation by switching between the pictures for the up or down movement.

History

Update 29.7.2014

  • Fixed some bugs.
  • Added function of border shown/hidden if focused/lost focus.
  • Changed Selector_Clicked Event now only one Parameter Result.
  • Changed the animation sequence.
  • Changed missing handles command in the Form of the test project.
  • Solved Focus problem if multiple instances on the same form.
  • Added the other IOS like Control IOSswitch to the Project familiy.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here