Solved

Form Controls

Posted on 2006-10-24
3
212 Views
Last Modified: 2006-11-23
Hi, does anyone know where i can get customised form controls that are bigger than the standard ones?

Like gaint combobox , listbox etc so it will be more suitable for touch screen applications.

thanks
0
Comment
Question by:jaxrpc
3 Comments
 
LVL 17

Expert Comment

by:ZeonFlash
Comment Utility
Generally speaking, controls resize themselves based on the size of the font being displayed in them.  Try experimenting with a listbox and setting the Font Size to 36 (larger or smaller to suit your taste).  
0
 
LVL 9

Accepted Solution

by:
jrscherer earned 500 total points
Comment Utility
There are no useful touch screen compatible windows controls available.
Also ZeonFlash's idea only works half. Font size does change some sizes, such as line width. bot other parts of a control are not affected and remain too small for finger touch activation. A ListBox for example has a scroll mechanism which remains too small in any case, even with super large font.

The only way to get one is to write it yourself. It is not too complex, ecpecially if you do not use all event functionalities of a normal control.

Below is the code of a "TouchListBox". It is derived from a UserControl. As you may figure out, it only uses two buttons as aditional controls. The rest is done in the OnPaint method.

Jack.net

Option Strict On


#Region " TouchListBox"

''' <summary>
''' Touch Sensor compatible List Box
''' </summary>
''' <remarks>by Company, Inc.</remarks>
Public Class TouchListBox

    Public Event SelectedIndexChanged(ByVal Sender As System.Object, ByVal e As System.EventArgs)

    Public Lines As New List(Of String)

    Dim szButtonSize As Size = New Size(64, 64)
    Dim colStripeColor As Color = Color.White
    Dim iLineHeight As Integer = 35
    Dim iSelectedLine As Integer = -1
    Dim iTopLine As Integer = 0 ' line number currently shown on top of visible window
    Dim TextRect As Rectangle '
    Dim ee As System.EventArgs = New EventArgs()
    Dim iVisibleLineCount As Integer
    Dim bSuspendRefresh As Boolean

    ' mouse related
    Dim bMouseDown As Boolean
    Dim bMouseHasDragged As Boolean
    Dim iMouseLastY As Integer
    Dim iMouseIncrement As Integer ' required pixels to do one increment

    ''' <summary>
    '''
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()
        InitializeComponent()
    End Sub

    ''' <summary>
    ''' Load Event
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub TouchListBox_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub

    ''' <summary>
    ''' Add a string to the List Box
    ''' </summary>
    ''' <param name="str"></param>
    ''' <remarks></remarks>
    Public Sub Add(ByVal str As String)
        Lines.Add(str)
        If Not bSuspendRefresh Then Refresh()
    End Sub

    ''' <summary>
    ''' Set / Get the button size
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property ButtonSize() As Size
        Get
            Return szButtonSize
        End Get
        Set(ByVal value As Size)
            szButtonSize = value
            If Not bSuspendRefresh Then Refresh()
        End Set
    End Property

    ''' <summary>
    ''' Set / get the Stripe Color
    ''' </summary>
    ''' <value>color</value>
    ''' <returns>color</returns>
    ''' <remarks>alternates with the background color</remarks>
    Public Property StripeColor() As Color
        Get
            Return colStripeColor
        End Get
        Set(ByVal value As Color)
            colStripeColor = value
            If Not bSuspendRefresh Then Refresh()
        End Set
    End Property

    ''' <summary>
    ''' get / set the hight of a line in pixel
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property LineHeight() As Integer
        Get
            Return iLineHeight
        End Get
        Set(ByVal value As Integer)
            iLineHeight = value
            If Not bSuspendRefresh Then Refresh()
        End Set
    End Property

    ''' <summary>
    ''' get / set the selected index
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>returns -1 if not selected</remarks>
    Public Property SelectedIndex() As Integer
        Get
            Return iSelectedLine
        End Get
        Set(ByVal value As Integer)
            iSelectedLine = value
            If Not bSuspendRefresh Then ShowSelectedItem(True) '
            If Not bSuspendRefresh Then Refresh()
            RaiseEvent SelectedIndexChanged(Me, ee) ' notify caller that index has changed
        End Set
    End Property

    ''' <summary>
    ''' get the selected text
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>returns String.empty if nothing is selected</remarks>
    Public ReadOnly Property SelectedText() As String
        Get
            If iSelectedLine = -1 Then
                Return (String.Empty)
            Else
                Return Lines(iSelectedLine)
            End If
        End Get
    End Property

    ''' <summary>
    ''' Clear the listbox
    ''' </summary>
    ''' <remarks>fires SelectedIndexChanged event if line was selected</remarks>
    Public Sub Clear()
        Lines.Clear()
        If Not bSuspendRefresh Then Refresh()
        CleanAll()
    End Sub

    ''' <summary>
    ''' Show the selected item by moving the list up or down
    ''' </summary>
    ''' <remarks>is ignored if SelectedIndex = -1</remarks>
    Public Sub ShowSelectedItem(Optional ByVal NoRefresh As Boolean = False)
        If iSelectedLine = -1 Then Exit Sub
        If Lines.Count - 1 > iVisibleLineCount Then
            Dim lineCount As Integer = Lines.Count - 1
            Dim centerLine As Integer = iVisibleLineCount \ 2
            Dim tmp As Integer = CInt(IIf(iSelectedLine <= (lineCount - centerLine - 1), iSelectedLine - centerLine, lineCount - iVisibleLineCount))
            iTopLine = CInt(IIf(tmp <= 0, 0, tmp))
            If (Not bSuspendRefresh) And (Not NoRefresh) Then Refresh()
        End If
    End Sub

    ''' <summary>
    ''' returns count of lines in listbox
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property count() As Integer
        Get
            Return Lines.Count
        End Get
    End Property

    ''' <summary>
    ''' return the string in index position
    ''' </summary>
    ''' <param name="index"></param>
    ''' <returns>string</returns>
    ''' <remarks>returns String.Empty if index is off bounds</remarks>
    Public Function Items(ByVal index As Integer) As String
        If index >= 0 And index <= Lines.Count - 1 Then
            Return Lines.Item(index)
        Else
            Return String.Empty
        End If
    End Function

    ''' <summary>
    ''' If true suspends update
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>Refresh if value = false</remarks>
    Public Property SuspendRefresh() As Boolean
        Get
            Return bSuspendRefresh
        End Get
        Set(ByVal value As Boolean)
            bSuspendRefresh = value
            If Not bSuspendRefresh Then Refresh()
        End Set
    End Property

    ' handle OnPaint event
    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Try
            Me.SuspendLayout()
            ' draw outfit here
            If Lines.Count > 0 Then

                Dim ShowScroll As Boolean = Lines.Count * iLineHeight > Me.Height
                iVisibleLineCount = CInt(Int(CSng(Me.Height) / CSng(LineHeight))) - 1

                Dim TxtBrush As New SolidBrush(Me.ForeColor)
                Dim StrpBrush As New SolidBrush(StripeColor)
                Dim frm As New StringFormat ' use frm object to define alignment

                e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit

                If ShowScroll Then

                    ' line count is larger than the display window > show scroll
                    ' size the lines
                    TextRect.Size = New Size(Me.Width - szButtonSize.Width, LineHeight)

                    ' place the buttons

                    Bu_SelectUp.Size = ButtonSize
                    Bu_SelectUp.Location = New Point(Me.Width - ButtonSize.Width, 0)
                    Bu_SelectUp.Visible = True

                    Bu_SelectDown.Size = ButtonSize
                    Bu_SelectDown.Location = New Point(Me.Width - ButtonSize.Width, Me.Height - ButtonSize.Height)
                    Bu_SelectDown.Visible = True

                    For i As Integer = 0 To iVisibleLineCount ' scan through all printable lines
                        TextRect.Location = New Point(0, i * LineHeight)
                        frm.Alignment = StringAlignment.Center
                        frm.LineAlignment = StringAlignment.Center

                        If i + iTopLine = iSelectedLine Then
                            e.Graphics.FillRectangle(TxtBrush, TextRect)
                            e.Graphics.DrawString(Lines.Item(i + iTopLine), Me.Font, StrpBrush, TextRect, frm)

                        Else

                            If i Mod 2 > 0 Then
                                e.Graphics.FillRectangle(StrpBrush, TextRect)
                            End If

                            e.Graphics.DrawString(Lines.Item(i + iTopLine), Me.Font, TxtBrush, TextRect, frm)
                        End If

                    Next

                    ' set button visibility
                    Bu_SelectUp.Enabled = (iTopLine > 0)
                    Bu_SelectDown.Enabled = iTopLine + iVisibleLineCount < Lines.Count - 1

                    ' show slider
                    Dim SliderRange As Integer = Me.Height - (ButtonSize.Height * 2) ' Slider Range in pixcels
                    Dim SliderHeight As Integer = CInt(CSng(SliderRange) * (CSng(iVisibleLineCount / CSng(Lines.Count - 1))))
                    Dim SliderVPos As Integer = ButtonSize.Height + (CInt((CSng(iTopLine) / CSng(Lines.Count - 1 - iVisibleLineCount)) * CSng(SliderRange - SliderHeight)))

                    ' calcualte and paint outline of slider
                    Dim SliderRectangle As Rectangle = New Rectangle(Me.Width - ButtonSize.Width, SliderVPos, ButtonSize.Width, SliderHeight)
                    e.Graphics.FillRectangle(TxtBrush, SliderRectangle)

                    ' calculate and paint fill area
                    With SliderRectangle
                        .Location = New Point(.Location.X + 2, .Location.Y + 2)
                        .Size = New Size(.Size.Width - 4, .Size.Height - 4)
                    End With
                    e.Graphics.FillRectangle(StrpBrush, SliderRectangle)
                    iMouseIncrement = CInt(CSng(SliderRange - SliderHeight) / CSng(Lines.Count - 1 - iVisibleLineCount))

                Else

                    ' lines fit into dispaly window >> no  vertical scroll
                    'size the lines
                    TextRect.Size = New Size(Me.Width, LineHeight)

                    ' hide the buttons
                    Bu_SelectUp.Visible = False
                    Bu_SelectDown.Visible = False

                    For i As Integer = 0 To Lines.Count - 1
                        TextRect.Location = New Point(0, i * LineHeight)
                        frm.Alignment = StringAlignment.Center
                        frm.LineAlignment = StringAlignment.Center

                        If i = iSelectedLine Then
                            e.Graphics.FillRectangle(TxtBrush, TextRect)
                            e.Graphics.DrawString(Lines.Item(i), Me.Font, StrpBrush, TextRect, frm)
                        Else
                            If i Mod 2 > 0 Then
                                e.Graphics.FillRectangle(StrpBrush, TextRect)
                            End If
                            e.Graphics.DrawString(Lines.Item(i), Me.Font, TxtBrush, TextRect, frm)
                        End If
                    Next
                End If
                TxtBrush.Dispose()
                StrpBrush.Dispose()

                Me.ResumeLayout()
            End If

            ' draw a single line frame around the control
            e.Graphics.DrawRectangle(New Pen(ForeColor), New Rectangle(0, 0, Me.Width - 1, Me.Height - 1))

        Catch ex As Exception
            Throw ex
        End Try

    End Sub

    ' helper to clean
    Private Sub CleanAll()
        Bu_SelectDown.Visible = False
        Bu_SelectUp.Visible = False
        iTopLine = 0
        If iSelectedLine > -1 Then
            iSelectedLine = -1
            RaiseEvent SelectedIndexChanged(Me, ee)
        End If
    End Sub

    ' event handler for Button Up click
    Private Sub Bu_SelectUp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Bu_SelectUp.Click
        If iTopLine > 0 Then iTopLine -= 1
        If Not bSuspendRefresh Then Refresh()
    End Sub

    '  event handler for Button Down Click
    Private Sub Bu_SelectDown_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Bu_SelectDown.Click
        iTopLine += 1
        If Not bSuspendRefresh Then Refresh()
    End Sub

    ' event handler for mouse down event
    Private Sub TouchListBox_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown

        ' remember the current point
        Dim MyPoint As Point = Me.PointToClient(Control.MousePosition)

        ' check if mouse is within scroll area
        If MyPoint.X > TextRect.Width Then
            If MyPoint.Y <= ButtonSize.Height Then Exit Sub ' within Up button
            If MyPoint.Y >= Me.Height - ButtonSize.Height Then Exit Sub ' within Down button

            ' mouse location is OK
            bMouseDown = True ' signal that mouse is legally down
            bMouseHasDragged = False ' iniialize the dragging sequence
            iMouseLastY = MyPoint.Y ' remember last y position for scrolling
        End If
    End Sub

    ' event handler for mouse move event
    Private Sub TouchListBox_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If Not bMouseDown Then Exit Sub ' mose not down

        ' remember the current point
        Dim MyPoint As Point = Me.PointToClient(Control.MousePosition)

        ' calculate y stroke since last processing
        Dim iStroke As Integer = MyPoint.Y - iMouseLastY

        ' check if stroke sufficient to do a scroll
        Dim Increments As Integer = Math.Abs(iStroke \ iMouseIncrement)
        '  If Math.Abs(iStroke) >= iMouseIncrement Then
        If Increments > 0 Then ' at least one step up or down

            ' stroke is big enough
            If iStroke > 0 Then ' check direction
                If Bu_SelectDown.Enabled Then iTopLine += Increments ' move downwards
                If iTopLine > Lines.Count - iVisibleLineCount - 1 Then
                    iTopLine = Lines.Count - iVisibleLineCount - 1
                End If

            Else
                If Bu_SelectUp.Enabled Then iTopLine -= Increments ' move upwards
                If iTopLine < 0 Then iTopLine = 0
            End If

            iMouseLastY = MyPoint.Y ' remember last processed y location

            If Not bSuspendRefresh Then Refresh() ' redraw the wholo bazard
            bMouseHasDragged = True ' rmember drag mode, as opposed to click mode
        End If
    End Sub

    ' event handler for Mouse Down
    Private Sub TouchListBox_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
        bMouseDown = False ' cycle legally ended

        ' check if this was a drag mode operation
        If bMouseHasDragged Then
            bMouseHasDragged = False
            Exit Sub ' do nothing in drag mode, since MouseMove event did the job
        End If

        ' process click mode
        Dim MyPoint As Point = Me.PointToClient(Control.MousePosition)
        If MyPoint.X > TextRect.Width Then

            ' click is in the right navigation area
            If MyPoint.Y <= ButtonSize.Height Then Exit Sub ' within Up button
            If MyPoint.Y >= Me.Height - ButtonSize.Height Then Exit Sub ' within Down button
            iTopLine = CInt((CSng(MyPoint.Y - ButtonSize.Height) / CSng(Me.Height - (2 * ButtonSize.Height))) * CSng(Lines.Count - 1 - iVisibleLineCount))

            If Not bSuspendRefresh Then Refresh()

        Else
            ' Click is in the line area
            ' calculate line in which mouse is clicked
            Dim ClickedLine As Integer = MyPoint.Y \ LineHeight

            If ClickedLine + iTopLine > Lines.Count - 1 Then Exit Sub ' click is below lowest line
            If ClickedLine > iVisibleLineCount Then Exit Sub ' in partial field at lower end

            ' select or deselect
            If iSelectedLine = -1 Then

                ' no selection was made, select now
                iSelectedLine = ClickedLine + iTopLine
            ElseIf iSelectedLine = ClickedLine + iTopLine Then

                ' line was already selected, deselect
                iSelectedLine = -1
            Else

                ' another line was selected
                iSelectedLine = ClickedLine + iTopLine
            End If

            If Not bSuspendRefresh Then Refresh()

            RaiseEvent SelectedIndexChanged(Me, ee) ' notify caller that index has changed
        End If
    End Sub
End Class


#End Region

Here is the code from TouchListBox.Designer.vb

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class TouchListBox
    Inherits System.Windows.Forms.UserControl

    'UserControl overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing AndAlso components IsNot Nothing Then
            components.Dispose()
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(TouchListBox))
        Me.Bu_SelectUp = New System.Windows.Forms.Button
        Me.Bu_SelectDown = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'Bu_SelectUp
        '
        Me.Bu_SelectUp.Image = CType(resources.GetObject("Bu_SelectUp.Image"), System.Drawing.Image)
        Me.Bu_SelectUp.Location = New System.Drawing.Point(344, 25)
        Me.Bu_SelectUp.Name = "Bu_SelectUp"
        Me.Bu_SelectUp.Size = New System.Drawing.Size(75, 76)
        Me.Bu_SelectUp.TabIndex = 1
        Me.Bu_SelectUp.UseVisualStyleBackColor = True
        '
        'Bu_SelectDown
        '
        Me.Bu_SelectDown.Image = CType(resources.GetObject("Bu_SelectDown.Image"), System.Drawing.Image)
        Me.Bu_SelectDown.Location = New System.Drawing.Point(344, 251)
        Me.Bu_SelectDown.Name = "Bu_SelectDown"
        Me.Bu_SelectDown.Size = New System.Drawing.Size(75, 76)
        Me.Bu_SelectDown.TabIndex = 2
        Me.Bu_SelectDown.UseVisualStyleBackColor = True
        '
        'TouchListBox
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.Controls.Add(Me.Bu_SelectDown)
        Me.Controls.Add(Me.Bu_SelectUp)
        Me.Name = "TouchListBox"
        Me.Size = New System.Drawing.Size(431, 362)
        Me.ResumeLayout(False)

    End Sub
    Friend WithEvents Bu_SelectUp As System.Windows.Forms.Button
    Friend WithEvents Bu_SelectDown As System.Windows.Forms.Button

End Class


0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now