Multiselecting user controls

Posted on 2007-03-28
Last Modified: 2013-11-26

Im working on a project which requires my application to have a calender to which i can load
the app's information.
Since its quite a customized calendar ive created 3 custom controls: the calendar which loads month controls which in turn load the day controls.

Obviously the day control is the most sophisticated one since the information is displayed on it.
This works great and also looks quite the way i wanted.

The only functionality missing is to be able to select more than one day control at a time with the mouse, kinda how you can select more than one day in the outlook calendar, just by clicking on one day and draggin the mouse to the last day needed.

Ive never done something like this with controls and i was wondering if its possible and how can i do it if it is?

Im working with VB.NET 2.0.

Thank you very much
Question by:unholly_plugin
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
LVL 86

Accepted Solution

Mike Tomlinson earned 125 total points
ID: 18809275
It is possible...albeit a pain in the butt...

I assume the "calendar" control holds instances of "month" and "day"?

Each day instance is a self contained unit and has no knowledge of the other days so this would have to happen at the calendar level.

What you could do is declare a custom even that the day control raises when the mouse is dragged in it.  Then the calendar control can trap that event and determine what other day controls need to be highlighted as a result of the drag.

Here is the basic concept.  Try it out with a blank form.  Remember, this is just to illustrate the idea so I have kept the logic at a minimum...

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Size = New Size(450, 300)
        Dim cal As New CalendarControl
        cal.Dock = DockStyle.Fill
    End Sub

    Public Class CalendarControl
        Inherits UserControl

        Private flp As FlowLayoutPanel

        Public Sub New()
            Dim dc As DayControl
            flp = New FlowLayoutPanel()
            flp.Dock = DockStyle.Fill
            flp.FlowDirection = FlowDirection.LeftToRight
            flp.WrapContents = True
            For i As Integer = 1 To 30
                dc = New DayControl(i)
                AddHandler dc.Dragging, AddressOf dc_Dragging
        End Sub

        Private Sub dc_Dragging(ByVal sender As DayControl, ByVal e As System.Windows.Forms.MouseEventArgs)
            Dim scrnPoint As Point = sender.PointToScreen(e.Location)
            Dim calPoint = flp.PointToClient(scrnPoint)
            Dim ctl As Control = flp.GetChildAtPoint(calPoint)
            If Not (ctl Is Nothing) Then
                If TypeOf ctl Is DayControl Then
                    Dim dc As DayControl = CType(ctl, DayControl)
                    If Not dc.selected Then
                        dc.selected = True
                    End If
                End If
            End If
        End Sub

    End Class

    Public Class DayControl
        Inherits UserControl

        Private dayOfMonth As Integer
        Public selected As Boolean = False

        Public ReadOnly Property Day() As String
                Return dayOfMonth
            End Get
        End Property

        Public Event Dragging(ByVal sender As DayControl, ByVal e As System.Windows.Forms.MouseEventArgs)

        Public Sub New()
        End Sub

        Public Sub New(ByVal dayOfMonth As Integer)
            Me.dayOfMonth = dayOfMonth
            Me.Size = New Size(75, 75)
            Me.BorderStyle = Windows.Forms.BorderStyle.FixedSingle
        End Sub

        Private Sub DayControl_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
            If e.Button = Windows.Forms.MouseButtons.Left Then
                Me.selected = Not Me.selected
            End If
        End Sub

        Private Sub DayControl_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
            If e.Button = Windows.Forms.MouseButtons.Left Then
                RaiseEvent Dragging(Me, e)
            End If
        End Sub

        Private Sub day_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
            If selected Then
                e.Graphics.FillRectangle(Brushes.Yellow, Me.ClientRectangle)
            End If
            e.Graphics.DrawString(Day, Me.Font, Brushes.Black, 0, 0)
        End Sub

    End Class

End Class

Author Comment

ID: 18837088
Thanks Alot,

I havent had a chance yet to really dive into your example code
but loading it in a project it looked just like what i needed.

Of course ill need to make some changes to fit it into my code
but i think you really nailed it! :)

Thanks again.
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 18837166
No problem.

Let me know if you need help applying the concept to your code.

This is a "grey area" of's not obvious how to do this at first as the process is started at a "low level" in the DayControl but has to invovle a "higher control" to achieve the end result.

In my example, the "source" DayControl has no idea what other DayControls have been affected by it...

Author Comment

ID: 18858087
Of course,

I also believe that this is the way it should be done.
From the application point of view, the Calendar control is the entry point to all the functionality.
of course the day and month controls need to provide information and specific functionality of their
own but its the Calendar object that needs to tie it all together.

Featured Post

Why You Need a DevOps Toolchain

IT needs to deliver services with more agility and velocity. IT must roll out application features and innovations faster to keep up with customer demands, which is where a DevOps toolchain steps in. View the infographic to see why you need a DevOps toolchain.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

710 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