ScottParker
asked on
User Control issue
I’m fairly certain that this is NOT what the person who told me to use a UserControl for this had in mind, but I couldn’t figure out how to reference other controls on the main form from the user control.
SOOO
In my windows forms project, I have a frmMain.
On that I have placed a user control that consists of 12 buttons. It’s a number pad. 0 – 9, a decimal point and a clear button.
The code below all works fine…. With one exception.
I cannot figure out how to “Hide” the user Control again. At least not consistently.
I have the pnlData_Click function below, and set that to fire when the background panel on the main form is clicked, but that is not always done because there are multiple other controls on the main form that can be clicked instead. I have also tried to add an event for when the usercontrol loses focus also... its not working.
Any ideas?
In the frmMain I have the following code.
SOOO
In my windows forms project, I have a frmMain.
On that I have placed a user control that consists of 12 buttons. It’s a number pad. 0 – 9, a decimal point and a clear button.
The code below all works fine…. With one exception.
I cannot figure out how to “Hide” the user Control again. At least not consistently.
I have the pnlData_Click function below, and set that to fire when the background panel on the main form is clicked, but that is not always done because there are multiple other controls on the main form that can be clicked instead. I have also tried to add an event for when the usercontrol loses focus also... its not working.
Any ideas?
In the frmMain I have the following code.
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
AddHandler UcNumPad1.btn0.Click, AddressOf UcNumPad1_Click
AddHandler UcNumPad1.btn1.Click, AddressOf UcNumPad1_Click
AddHandler UcNumPad1.btn2.Click, AddressOf UcNumPad1_Click
AddHandler UcNumPad1.btn3.Click, AddressOf UcNumPad1_Click
AddHandler UcNumPad1.btn4.Click, AddressOf UcNumPad1_Click
AddHandler UcNumPad1.btn5.Click, AddressOf UcNumPad1_Click
AddHandler UcNumPad1.btn6.Click, AddressOf UcNumPad1_Click
AddHandler UcNumPad1.btn7.Click, AddressOf UcNumPad1_Click
AddHandler UcNumPad1.btn8.Click, AddressOf UcNumPad1_Click
AddHandler UcNumPad1.btn9.Click, AddressOf UcNumPad1_Click
AddHandler UcNumPad1.btnClear.Click, AddressOf UcNumPad1_Click
AddHandler UcNumPad1.btnDec.Click, AddressOf UcNumPad1_Click
AddHandler UcNumPad1.VisibleChanged, AddressOf UcNumPad1_VisibleChanged
AddHandler UcNumPad1.Leave, AddressOf UcNumPad1_VisibleChanged
End Sub
Private Sub txtItemQty_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs)
Try
Dim temTextBox As New TextBox
temTextBox = sender
_CurrentTextBox = sender.Name
pnlData.Controls.Add(UcNumPad1)
UcNumPad1.Location = New System.Drawing.Point(280, temTextBox.Location.Y + 20)
UcNumPad1.BringToFront()
UcNumPad1.Visible = True
UcNumPad1.Focus()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub UcNumPad1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim txtTextBox() As Control = pnlData.Controls.Find(_CurrentTextBox, True)
Select Case sender.name
Case "btnClear"
txtTextBox(0).Text = ""
Case "btn1"
txtTextBox(0).Text = txtTextBox(0).Text & "1"
Case "btn2"
txtTextBox(0).Text = txtTextBox(0).Text & "2"
Case "btn3"
txtTextBox(0).Text = txtTextBox(0).Text & "3"
Case "btn4"
txtTextBox(0).Text = txtTextBox(0).Text & "4"
Case "btn5"
txtTextBox(0).Text = txtTextBox(0).Text & "5"
Case "btn6"
txtTextBox(0).Text = txtTextBox(0).Text & "6"
Case "btn7"
txtTextBox(0).Text = txtTextBox(0).Text & "7"
Case "btn8"
txtTextBox(0).Text = txtTextBox(0).Text & "8"
Case "btn9"
txtTextBox(0).Text = txtTextBox(0).Text & "9"
Case "btn0"
txtTextBox(0).Text = txtTextBox(0).Text & "0"
Case "btnDec"
txtTextBox(0).Text = txtTextBox(0).Text & "."
End Select
End Sub
Private Sub UcNumPad1_VisibleChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
If Visible = True Then
Dim txtTextBox() As Control = pnlData.Controls.Find(_CurrentTextBox, True)
txtTextBox(0).BackColor = Color.Plum
Else
Dim txtTextBox() As Control = pnlData.Controls.Find(_CurrentTextBox, True)
txtTextBox(0).BackColor = Color.White
End If
End Sub
Private Sub pnlData_Click(sender As System.Object, e As System.EventArgs) Handles pnlData.Click, Panel1.Click
UcNumPad1.Visible = False
End Sub
you can try use the lost focus event
ASKER
I already tried to add an event for when the usercontrol loses focus. No luck.
I think its because the buttons on the user control itself is what has focus.
I think its because the buttons on the user control itself is what has focus.
Could you post a example, to work with it
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
If you have a look at MSDN LostFocus documentation you will see that Microsoft recommends using Enter and Leave events rather than GotFocus and LostFocus.
the event is fired when you click another part of the form or not?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Idle_Mind
Ok, that code does make more sense now.
The only thing I think its missing is how to "Show" and "Hide" the user control.
I assume to show it, I would just add the visible = true command to the TB_GotFocus function you mentioned. I can also put the location code there.. i.e. where on the screen I want the user control to show up.
But when the user is done, and touches (touch screen monitor) another part of the screen how do I make the user control "Hide" again.
edit( you posted while I was typing this)
Crashman,
yes the event is fired when another part of the form is clicked.. UNLESS the point of the click hapens to be on top of another control that is on the form. That is what makes this so ugly.
Ok, that code does make more sense now.
The only thing I think its missing is how to "Show" and "Hide" the user control.
I assume to show it, I would just add the visible = true command to the TB_GotFocus function you mentioned. I can also put the location code there.. i.e. where on the screen I want the user control to show up.
But when the user is done, and touches (touch screen monitor) another part of the screen how do I make the user control "Hide" again.
edit( you posted while I was typing this)
Crashman,
yes the event is fired when another part of the form is clicked.. UNLESS the point of the click hapens to be on top of another control that is on the form. That is what makes this so ugly.
Exactly...just set the Visible() property to True and make its Location() property what you want.
The second post I made makes the NumPad automatically hide itself when the user clicks (or touches) somewhere outside the control. This magic is accomplished using IMessageFilter to trap the WM_LBUTTONDOWN message and then compare the current screen coords to that of the UserControl.
The second post I made makes the NumPad automatically hide itself when the user clicks (or touches) somewhere outside the control. This magic is accomplished using IMessageFilter to trap the WM_LBUTTONDOWN message and then compare the current screen coords to that of the UserControl.
ASKER
Thank you once again. Your code worked perfectly. I even kind of understand it now.
"I even kind of understand it now."
That's the best part. =)
Do you still have any questions about the code that I can answer?
That's the best part. =)
Do you still have any questions about the code that I can answer?
ASKER
No, I think I got the idea now...
I added
AddHandler UcNumPad1.VisibleChanged, AddressOf UcNumPad1_VisibleChanged
to the main form so that way I could change the background color of the _CurrentTextBox.
I also looked at the _MyFilter_MouseDown() and noticed how you picked a rectangle that is where the user control is, and if the mouse is outside of that rectangle, then turn the visible to false.
I don't pretend to understand exactly how the MyFilter class works, but it does so for now I am happy.
All in all in the last 2 days I learned a lot about User Controls and have decided to now add another one to this project to handle a different issue.
Thanks again
I added
AddHandler UcNumPad1.VisibleChanged, AddressOf UcNumPad1_VisibleChanged
to the main form so that way I could change the background color of the _CurrentTextBox.
I also looked at the _MyFilter_MouseDown() and noticed how you picked a rectangle that is where the user control is, and if the mouse is outside of that rectangle, then turn the visible to false.
I don't pretend to understand exactly how the MyFilter class works, but it does so for now I am happy.
All in all in the last 2 days I learned a lot about User Controls and have decided to now add another one to this project to handle a different issue.
Thanks again
IMessageFilter allows your application to trap and filter windows messages before they get dispatched to the current form/control. It's a low level technique that doesn't need to be used very often, as a solution can usually be derived by overriding WndProc() for a specific form/control. In this case, though, we needed to know when the mouse was clicked anywhere on the form so I needed a common area outside any specific form/control; IMessageFilter fits the bill perfectly for this situation.