Link to home
Start Free TrialLog in
Avatar of ScottParker
ScottParkerFlag for United States of America

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.
    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

Open in new window

Avatar of Haver Ramirez
Haver Ramirez

you can try use the lost focus event
Avatar of ScottParker

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.
Could you post a example, to work with it
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
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.
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?
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
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.