-
Strange Coloring
I have a custom control that consists of a textbox and two buttons. There is a grid of these controls in the program. In the control, I have this property:
Code:
Public Overrides Property ForeColor As System.Drawing.Color
Get
Return tbEntry.ForeColor
End Get
Set(value As System.Drawing.Color)
tbEntry.ForeColor = value
bComment.ForeColor = Drawing.Color.Black
bMark.ForeColor = Drawing.Color.Black
End Set
End Property
The intention is that when a certain action happens, the forecolor of the textbox changes color. In practice, it will either change to red or black.
My question is about the two lines that change the fore colors of the two buttons. If those lines are there, all is well, if those lines are not there, a very peculiar thing is happening: After the action that causes the textbox forecolor to become red, if I then move the mouse over the grid, some number of buttons will change their forecolor to red. After a few buttons have changed color (1-5, perhaps), the effect will end. The buttons that will change color need not be in any way related to the control that changed to red.
There is no code in the program that will change the forecolor of the buttons, as they are supposed to remain black at all times. Just to be sure, I've looked for all instances of Red, and all instances of ForeColor (all of which are shown in that code snippet). I also confirmed that the call to the ForeColor property of the user control is not called when it shouldn't be, though the buttons that get colored are whatever the mouse moves over, and need not be the control that got colored.
I suspect that the key point in that property is that the final line is setting a color to black, and that somehow the mouse is causing some strange painting issue such that it paints the forecolor to whatever the last color used was, but that's absurd. It just happens to fit the behavior.
Can anybody explain what is going on?
-
Re: Strange Coloring
What code do you have in place either in the control itself or in the program for Mouse movement events?
-
Re: Strange Coloring
The answer to that is going to have to wait, as I don't have it handy. In general, I was pre-filtering mouse messages and handling the Mouse Move and Mouse Up messages. This had nothing to do with coloring things red, it was part of a drag copy action where the mouse down event captured the mouse, then mouse move events were used to select/deselect textboxes, with the selected ones being colored a light green. Either mouse up, or leaving the grid entirely, would end the mouse capture, with mouse up resulting in the copy action.
New data entered into a textbox, either directly or by that drag copy, would cause the text for the new values to be red, which is what that property is about. Only the text in the textbox, though, never the buttons. Still, I thought that drag copy might still happening, even after the mouse up, but every test I could think of showed that it was not. The back color was never set to green, breakpoints and logging showed that drag copy did, in fact, end when it should, and so forth.
-
Re: Strange Coloring
This is ho 'Tw the mouse movements are handled, it's all a prefilter on the messages:
Code:
Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
If Not Me.pDisplaySurface.IsDisposed Then
If Me.IsHandleCreated Then
If m.HWnd = mInitiatorHandle Then
Dim pt As Drawing.Point = Me.pDisplaySurface.PointToClient(MousePosition)
If Me.pDisplaySurface.ClientRectangle.Contains(pt) Then
Dim mtb As MortalityTB = Nothing
If m.Msg = WM_MOUSEMOVE Then
'Only do anything if the mouse is caught. Event then, do something on only two cases:
'1: Not on the original cell. OR
'2: On the original cell, but others have been selected.
If mMouseCaught Then
For Each mtb In mControls
If mtb.Bounds.Contains(pt) Then
Exit For
End If
Next
If mtb IsNot mStartMTB OrElse mSelMan.SomeSelections Then
If mtb.RUID <> selP.RUID Then
mCount = mCount
selP = New SelectionPoint(mtb.DayShown, mtb.RUID)
End If
If Me.horScroll.Bounds.Contains(pt) Then
Me.Cursor = Cursors.PanSouth
mOrdinal = 3
ScrollTimer.Start()
ElseIf mRightRectangle.Contains(pt) Then
Me.Cursor = Cursors.PanEast
mOrdinal = 2
ScrollTimer.Start()
ElseIf mColRectangle.Contains(pt) Then
Me.Cursor = Cursors.PanNorth
mOrdinal = 1
ScrollTimer.Start()
ElseIf mRowRectangle.Contains(pt) Then
Me.Cursor = Cursors.PanWest
mOrdinal = 4
ScrollTimer.Start()
Else
Me.Cursor = Cursors.Default
mOrdinal = 0
ScrollTimer.Stop()
End If
ManageSelections(pt)
End If
End If
ElseIf m.Msg = WM_LBUTTONUP Then
Me.Cursor = Cursors.Default
If mMouseCaught Then
mMouseCaught = False
mStartMTB = Nothing
CopySelection()
mSelMan.Clear()
End If
End If
Else
'Anything that happens outside, as long as the mouse is caught, should cause the end of the mouse capture.
Me.Cursor = Cursors.Default
If mMouseCaught Then
mInitiatorHandle = Nothing
mMouseCaught = False
mStartMTB = Nothing
mSelMan.Clear()
End If
End If
End If
End If
End If
'This is just an intercept, so always return false.
Return False
End Function
MTB stands for the custom control, which are arranged in a grid on a panel. It looks much like a DGV, but is not. There are row labels and column headers, but those are just labels that are also arranged on the panel. There may also be scroll bars, but the panel does not scroll. All the labels and the controls are fixed in number and location. If the user moves the scroll bar, it changes what is displayed in the labels and the MTB controls, but they don't move. That gives the user the appearance of scrolling up, down, left, and right, but in fact they are not. They are just refilling the controls based on the setting of the scroll bars. That's pretty much how all scrollable controls work anyways.
Scrolling is irrelevant to this question. I haven't actually tried scrolling the incorrectly colored items off the screen to see what happens, but this shows what the mouse events are.
In that code, it is only CopySelection that will cause the forecolor to be red. The code that does that is here, and most of it is meaningless to anyone else:
Code:
For Each ctl In mControls
If ctl.DayShown = mSelMan.SelectionList(x).Day AndAlso ctl.RUID = mSelMan.SelectionList(x).RUID Then
Dim ttime = GetEstimatedMortalityTime(mSelMan.SelectionList(x).RUID, New Date(mSelYear, Me.cbMonth.SelectedIndex + 1, mSelMan.SelectionList(x).Day))
'Only add an undo point if the control is enabled.
If ctl.PseudoEnable Then
Integer.TryParse(ctl.Text, i)
nl.Add(New UndoPoint(mSelMan.SelectionList(x).Day, Me.cbMonth.SelectedIndex + 1, mSelYear, ttime.Hour, ttime.Minute, mSelMan.SelectionList(x).RUID, i, ni))
ctl.Text = mSelMan.InitialValue
ctl.ForeColor = Drawing.Color.Red
End If
'Either way, set the flag and exit the loop.
flag = True
Exit For
End If
Next
The purpose is for drag copying a value from one cell to several. Some cells could be disabled, some could be irrelevant, but if enabled and relevant, then set the text and set the color.
-
Re: Strange Coloring
I am setting the ForeColor property on a custom control that includes a series of other controls. The ForeColor property is overridden for the custom control. If the overriding property automatically called the base property of the same name, it would make sense that all three elements would change their fore color, but only for the control in question. What I am seeing is that the forecolor changes for a variety of OTHER custom controls, but now that I think about it, there are aspects of that which I haven't investigated fully, and which I can't look at right now.