By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,124 Members | 1,575 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,124 IT Pros & Developers. It's quick & easy.

Capture Month Change with MonthCalendar

P: n/a
I have a MonthCalendar on one of my forms. I have disovered that the
DateChanged event is triggered not only when the user clicks on a new
date, but also if they click on the Previous or Next Month arrows
(meaning they click on either of the left or right pointing arrows in
the top corner). If the user changes the month, it messes up some of
the date logic that I have in the DateChanged event. Does anybody
know how I can capture this action? I'd like my code in the
DateChanged routine to work like this:

If MonthNotChanged then
Do Something
Else 'month changed
Do something Else
End if

Thanks,
Randy

Oct 7 '07 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Randy,

Did you try the other events, I use always the TextChanged one?

Cor
Oct 7 '07 #2

P: n/a
I don't see TextChanged in the list of events. I looked at the other
events, but I don't see anything that is more appropriate.

Oct 7 '07 #3

P: n/a

http://msdn2.microsoft.com/en-us/lib...xtchanged.aspx
>I don't see TextChanged in the list of events. I looked at the other
events, but I don't see anything that is more appropriate.
Oct 8 '07 #4

P: n/a
Charlie,
I was going down the same path with using an If statement to check if
the month had changed. Unfortunately, this doesn't always work. If
you look at the calendar view, you can often see the last few days of
the previous month or the first few days of the succeeding month. If
the user were to click on these dates, the logic you propose would
conclude that the user had clicked the arrow, not the date. I'll post
my code below for anybody who is interested.

What I am trying to do is execute certain lines of code *only* if the
user has selected a date. If they are clicking on one of the arrows,
I am treating this action as the user *navigating* to a date (as
opposed to actually selecting one). So if they were to click Sep 28
while viewing the Oct calendar, this would qualify as *selecting* a
date, and thus would initiate a sequence of actions. If they clicked
the left arrow, this is simply a navigational move and would be
disregarded. I've looked for patterns in how the MonthCalendar
handles these arrow clicks, but I'm not seeing reliable patterns that
I can code around.

Somehow, the control must distinguish these arrows or it wouldn't work
as it does. So the question is still, how can I trap these clicks in
my VB code? If I can figure that out, it will make my programming
monumentally easier as well as more reliable.
Private Sub MonthCalendar1_DateChanged(ByVal sender As Object, ByVal e
As System.Windows.Forms.DateRangeEventArgs) Handles
MonthCalendar1.DateChanged
'If there are unsaved changes, alert the user
If bLoading = False Then
If bUnsaved = True Then
frmDateChange.Show()
Exit Sub
End If

'This is where I'm stuck trying to trap the arrow click
Dim d As Date = e.Start
'Me.Text = Me.CurrentSelectedDate
If d.AddMonths(-1).Month = Me.CurrentSelectedDate.Month
Then
If d.Day = 1 Then
Me.Text = d.ToString & " Right arrow clicked."
Call SelectDates()
End If
ElseIf d.AddMonths(1).Month = Me.CurrentSelectedDate.Month
Then
If d.Day = 1 Then
Me.Text = d.ToString & " Left arrow clicked."
Call SelectDates()
End If
Else
Me.Text = d.ToString & " Date changed."
Call SelectDates()
Call RemoveControls()
Call AddDataRows()
End If
Me.CurrentSelectedDate = d
End If
End Sub

Private Sub SelectDates()
Dim i As Integer =
CInt(MonthCalendar1.SelectionStart.DayOfWeek)
Dim d As Date = MonthCalendar1.SelectionStart
Dim a As Integer
If i = 0 Then
a = -6
Else
a = 1 - i
End If
MonthCalendar1.SelectionStart = d.AddDays(a)

If i = 0 Then
a = 0
Else
a = 7 - i
End If
MonthCalendar1.SelectionEnd = d.AddDays(a)
End Sub

So, how do I trap this arrow click? Or if there is no way, how can I
program the logic to identify and trap the conditions that would would
be present if the arrows are clicked? Any help is appreciated.

Thanks,
Randy

Oct 9 '07 #5

P: n/a
You could add another event handler to the code I previously provided...In
fact, this would probably do it on its own...

The MonthCalendar.MouseDown event (e as MouseEventArgs) captures the X and Y
coordinates relative to the control itself...My test shows that Y < 24 for a
click of the month buttons...

"Randy" wrote:
Charlie,
I was going down the same path with using an If statement to check if
the month had changed. Unfortunately, this doesn't always work. If
you look at the calendar view, you can often see the last few days of
the previous month or the first few days of the succeeding month. If
the user were to click on these dates, the logic you propose would
conclude that the user had clicked the arrow, not the date. I'll post
my code below for anybody who is interested.

What I am trying to do is execute certain lines of code *only* if the
user has selected a date. If they are clicking on one of the arrows,
I am treating this action as the user *navigating* to a date (as
opposed to actually selecting one). So if they were to click Sep 28
while viewing the Oct calendar, this would qualify as *selecting* a
date, and thus would initiate a sequence of actions. If they clicked
the left arrow, this is simply a navigational move and would be
disregarded. I've looked for patterns in how the MonthCalendar
handles these arrow clicks, but I'm not seeing reliable patterns that
I can code around.

Somehow, the control must distinguish these arrows or it wouldn't work
as it does. So the question is still, how can I trap these clicks in
my VB code? If I can figure that out, it will make my programming
monumentally easier as well as more reliable.
Private Sub MonthCalendar1_DateChanged(ByVal sender As Object, ByVal e
As System.Windows.Forms.DateRangeEventArgs) Handles
MonthCalendar1.DateChanged
'If there are unsaved changes, alert the user
If bLoading = False Then
If bUnsaved = True Then
frmDateChange.Show()
Exit Sub
End If

'This is where I'm stuck trying to trap the arrow click
Dim d As Date = e.Start
'Me.Text = Me.CurrentSelectedDate
If d.AddMonths(-1).Month = Me.CurrentSelectedDate.Month
Then
If d.Day = 1 Then
Me.Text = d.ToString & " Right arrow clicked."
Call SelectDates()
End If
ElseIf d.AddMonths(1).Month = Me.CurrentSelectedDate.Month
Then
If d.Day = 1 Then
Me.Text = d.ToString & " Left arrow clicked."
Call SelectDates()
End If
Else
Me.Text = d.ToString & " Date changed."
Call SelectDates()
Call RemoveControls()
Call AddDataRows()
End If
Me.CurrentSelectedDate = d
End If
End Sub

Private Sub SelectDates()
Dim i As Integer =
CInt(MonthCalendar1.SelectionStart.DayOfWeek)
Dim d As Date = MonthCalendar1.SelectionStart
Dim a As Integer
If i = 0 Then
a = -6
Else
a = 1 - i
End If
MonthCalendar1.SelectionStart = d.AddDays(a)

If i = 0 Then
a = 0
Else
a = 7 - i
End If
MonthCalendar1.SelectionEnd = d.AddDays(a)
End Sub

So, how do I trap this arrow click? Or if there is no way, how can I
program the logic to identify and trap the conditions that would would
be present if the arrows are clicked? Any help is appreciated.

Thanks,
Randy

Oct 9 '07 #6

P: n/a
The mousedown event happens AFTER the datechanged event, so you may have to
capture any needed parameters in the datechanged event, and let the mousedown
event act on those parameters after determining where the user clicked...

As I was writing the previous note, I assumed the events processed in
reverse to how they actually process...Oh well, it really should not be much
of a problem.

"Randy" wrote:
Charlie,
I was going down the same path with using an If statement to check if
the month had changed. Unfortunately, this doesn't always work. If
you look at the calendar view, you can often see the last few days of
the previous month or the first few days of the succeeding month. If
the user were to click on these dates, the logic you propose would
conclude that the user had clicked the arrow, not the date. I'll post
my code below for anybody who is interested.

What I am trying to do is execute certain lines of code *only* if the
user has selected a date. If they are clicking on one of the arrows,
I am treating this action as the user *navigating* to a date (as
opposed to actually selecting one). So if they were to click Sep 28
while viewing the Oct calendar, this would qualify as *selecting* a
date, and thus would initiate a sequence of actions. If they clicked
the left arrow, this is simply a navigational move and would be
disregarded. I've looked for patterns in how the MonthCalendar
handles these arrow clicks, but I'm not seeing reliable patterns that
I can code around.

Somehow, the control must distinguish these arrows or it wouldn't work
as it does. So the question is still, how can I trap these clicks in
my VB code? If I can figure that out, it will make my programming
monumentally easier as well as more reliable.
Private Sub MonthCalendar1_DateChanged(ByVal sender As Object, ByVal e
As System.Windows.Forms.DateRangeEventArgs) Handles
MonthCalendar1.DateChanged
'If there are unsaved changes, alert the user
If bLoading = False Then
If bUnsaved = True Then
frmDateChange.Show()
Exit Sub
End If

'This is where I'm stuck trying to trap the arrow click
Dim d As Date = e.Start
'Me.Text = Me.CurrentSelectedDate
If d.AddMonths(-1).Month = Me.CurrentSelectedDate.Month
Then
If d.Day = 1 Then
Me.Text = d.ToString & " Right arrow clicked."
Call SelectDates()
End If
ElseIf d.AddMonths(1).Month = Me.CurrentSelectedDate.Month
Then
If d.Day = 1 Then
Me.Text = d.ToString & " Left arrow clicked."
Call SelectDates()
End If
Else
Me.Text = d.ToString & " Date changed."
Call SelectDates()
Call RemoveControls()
Call AddDataRows()
End If
Me.CurrentSelectedDate = d
End If
End Sub

Private Sub SelectDates()
Dim i As Integer =
CInt(MonthCalendar1.SelectionStart.DayOfWeek)
Dim d As Date = MonthCalendar1.SelectionStart
Dim a As Integer
If i = 0 Then
a = -6
Else
a = 1 - i
End If
MonthCalendar1.SelectionStart = d.AddDays(a)

If i = 0 Then
a = 0
Else
a = 7 - i
End If
MonthCalendar1.SelectionEnd = d.AddDays(a)
End Sub

So, how do I trap this arrow click? Or if there is no way, how can I
program the logic to identify and trap the conditions that would would
be present if the arrows are clicked? Any help is appreciated.

Thanks,
Randy

Oct 9 '07 #7

P: n/a
And just in case you're not always depending on a mouse click for a date
change, you could use a timer to postpone the code of the datechanged event
(maybe 100 ms?, to see if the mouseclick occurred.

"Randy" wrote:
Charlie,
I was going down the same path with using an If statement to check if
the month had changed. Unfortunately, this doesn't always work. If
you look at the calendar view, you can often see the last few days of
the previous month or the first few days of the succeeding month. If
the user were to click on these dates, the logic you propose would
conclude that the user had clicked the arrow, not the date. I'll post
my code below for anybody who is interested.

What I am trying to do is execute certain lines of code *only* if the
user has selected a date. If they are clicking on one of the arrows,
I am treating this action as the user *navigating* to a date (as
opposed to actually selecting one). So if they were to click Sep 28
while viewing the Oct calendar, this would qualify as *selecting* a
date, and thus would initiate a sequence of actions. If they clicked
the left arrow, this is simply a navigational move and would be
disregarded. I've looked for patterns in how the MonthCalendar
handles these arrow clicks, but I'm not seeing reliable patterns that
I can code around.

Somehow, the control must distinguish these arrows or it wouldn't work
as it does. So the question is still, how can I trap these clicks in
my VB code? If I can figure that out, it will make my programming
monumentally easier as well as more reliable.
Private Sub MonthCalendar1_DateChanged(ByVal sender As Object, ByVal e
As System.Windows.Forms.DateRangeEventArgs) Handles
MonthCalendar1.DateChanged
'If there are unsaved changes, alert the user
If bLoading = False Then
If bUnsaved = True Then
frmDateChange.Show()
Exit Sub
End If

'This is where I'm stuck trying to trap the arrow click
Dim d As Date = e.Start
'Me.Text = Me.CurrentSelectedDate
If d.AddMonths(-1).Month = Me.CurrentSelectedDate.Month
Then
If d.Day = 1 Then
Me.Text = d.ToString & " Right arrow clicked."
Call SelectDates()
End If
ElseIf d.AddMonths(1).Month = Me.CurrentSelectedDate.Month
Then
If d.Day = 1 Then
Me.Text = d.ToString & " Left arrow clicked."
Call SelectDates()
End If
Else
Me.Text = d.ToString & " Date changed."
Call SelectDates()
Call RemoveControls()
Call AddDataRows()
End If
Me.CurrentSelectedDate = d
End If
End Sub

Private Sub SelectDates()
Dim i As Integer =
CInt(MonthCalendar1.SelectionStart.DayOfWeek)
Dim d As Date = MonthCalendar1.SelectionStart
Dim a As Integer
If i = 0 Then
a = -6
Else
a = 1 - i
End If
MonthCalendar1.SelectionStart = d.AddDays(a)

If i = 0 Then
a = 0
Else
a = 7 - i
End If
MonthCalendar1.SelectionEnd = d.AddDays(a)
End Sub

So, how do I trap this arrow click? Or if there is no way, how can I
program the logic to identify and trap the conditions that would would
be present if the arrows are clicked? Any help is appreciated.

Thanks,
Randy

Oct 9 '07 #8

P: n/a
Thanks a lot, Charlie. These are great suggestions. I'm having a
little trouble implementing it, however, as I cannot get predictable
values for the coordinates where the arrows would have to exist.
Since this is a separate topic from just determining if the arrow has
been clicked, I started a new post. (search: Find Mouse Coordinates
Within Control). I'd appreciate if you have any ideas.

Thanks again for all of your help. I really appreciate it.
Randy

Oct 11 '07 #9

P: n/a
Hi Randy,

I am having the same problem. I need to know whether they clicked on the arrow to change the month or actually selected a date.

I have you had any luck solving this? Can you post your solution?

In the meantime, I will continue researching for some solution. I will post if I have any success.

This seems so basic. I'm sure we'll find a solution.

Thanks,
Annie

EggHeadCafe - .NET Developer Portal of Choice
http://www.eggheadcafe.com
Oct 14 '07 #10

P: n/a

Hi Randy,
I found a solution that works very well for me.

private void monthCalendarDate_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e) {

MonthCalendar.HitTestInfo oHTI = monthCalendarDate.HitTest(e.X,e.Y);

if ( oHTI.HitArea == MonthCalendar.HitArea.PrevMonthButton){
MessageBox.Show("Left arrow hit");
return;
}

if ( oHTI.HitArea == MonthCalendar.HitArea.NextMonthButton)
{
MessageBox.Show("Right arrow hit");

return;

}

if ( oHTI.HitArea == MonthCalendar.HitArea.Date ||
oHTI.HitArea == MonthCalendar.HitArea.PrevMonthDate ||
oHTI.HitArea == MonthCalendar.HitArea.NextMonthDate){
this.txtJobDate.Text =
this.dateValue_Renamed; this.monthCalendarDate.Visible = false;

}
}
You can detect in MouseDown event using the hitarea. In my case I only
wanted to set the visible property of my monthcalendar to false if they
actually entered a date.

dateVakye_Renamed is a global variable I set in the datechange event.

Hope this helps you.

Annie

*** Sent via Developersdex http://www.developersdex.com ***
Oct 14 '07 #11

P: n/a
Charlie,
I've been working at implementing your solution and have a few
questions:
>"Create a form level variable that will hold your
DateRangeEventArgs until the timer fires...Private DateRangeEventArgs
as DateRangeEventArgs."

Not sure how to do this. I know how to work with date variables, but
not with the type 'DateRangeEventArgs'. Can you show me how to
capture these?

I've created a blank form with nothing but a MonthCalendar on it to
strip this issue down to the basics.

Here is the code that I have written thus far. Do you see where it is
going wrong? Things seem to work correctly on the first pass, but
subsequent passes don't yield the correct answer.

Thanks again for your help.
Randy
Imports System.Windows.Forms

Public Class Form1

Private DateRangeEventArgs As DateRangeEventArgs
Private MouseEventArgs As MouseEventArgs
Dim bArrow As Boolean = False
Private Shared myTimer As New System.Windows.Forms.Timer()

Private Sub Form1_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
AddHandler myTimer.Tick, AddressOf TimerEventProcessor
myTimer.Interval = 100
End Sub

Private Sub TimerEventProcessor(ByVal myObject As Object, ByVal
myEventArgs As EventArgs)
myTimer.Stop()
If bArrow = False Then
Me.Text = "Date Selected"
Else
Me.Text = "Arrow Clicked"
End If

Me.MouseEventArgs = Nothing
Me.DateRangeEventArgs = Nothing
End Sub

Private Sub MonthCalendar1_DateChanged(ByVal sender As Object,
ByVal e As System.Windows.Forms.DateRangeEventArgs) Handles
MonthCalendar1.DateChanged
DateRangeEventArgs =
myTimer.Enabled = True
Application.DoEvents()
End Sub

Private Sub MonthCalendar1_MouseDown(ByVal sender As Object, ByVal
e As System.Windows.Forms.MouseEventArgs) Handles
MonthCalendar1.MouseDown
Dim x As Integer = e.X
Dim y As Integer = e.Y

If x >= 5 Then
If x <= 20 Then
If y >= 11 Then
If y <= 26 Then
'Me.Text = "Left Arrow Clicked"
bArrow = True
End If
End If
End If
End If

If x >= 206 Then
If x <= 221 Then
If y >= 11 Then
If y <= 26 Then
'Me.Text = "Right Arrow Clicked"
bArrow = True
End If
End If
End If
End If

End Sub
End Class

Oct 14 '07 #12

This discussion thread is closed

Replies have been disabled for this discussion.