Context menu manipulation


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 9 of 9

Thread: Context menu manipulation

Hybrid View

  1. #1
    nnch97 Guest

    Context menu manipulation


    Hi,

    I want to control the location of the context menu linked with a button in
    VB.Net. The requirement is to be able to show the menu on clicking the button,
    with x and y location as follows:
    x: either at the left edge or the right edge of the button,
    y: either starting at the botton edge of the button (for down context menu)
    OR ending at the upper edge of the button (for up context menu).

    Your suggestions for this would be highly appreciated
    Thanks



  2. #2
    PWilmarth Guest

    Re: Context menu manipulation


    If I understand your question correctly:


    You need to create a rectangle that defines the area where the
    the context menu is active(or can be shown). Defining this rectangle will
    be your challenge, but the rectangle will give you X and Y points that you
    are valid points that can respond to MouseEvents.

    Then code some MouseEvents(Button1_MouseHover, Button1_MouseEnter, Button1_MouseDown)
    that handle the event. If the Mouse is within your rectangle, the context
    menu is active (you could use the Show Method).

    The following comes from the .NET OnLine Help, but it gives some useful
    hints about how to attack your problem. It overrides the base class event
    OnMouseMove.

    Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
    SetDragValue(New Point(e.X, e.Y))
    End Sub

    Private Sub SetDragValue(ByVal mouseLocation As Point)

    Dim client As Rectangle = ClientRectangle

    If (client.Contains(mouseLocation)) Then

    If (client.Y <= mouseLocation.Y And mouseLocation.Y <= client.Y
    + client.Height) Then
    If (mouseLocation.X <= client.X And mouseLocation.X >
    client.X - LeftRightBorder) Then
    Dim newDragValue As Integer = Min
    If (newDragValue <> dragValue) Then
    Dim old As Integer = dragValue
    dragValue = newDragValue
    OptimizedInvalidate(old, dragValue)
    End If

    ElseIf (mouseLocation.X >= client.X + client.Width And
    mouseLocation.X < client.X + client.Width + LeftRightBorder) Then
    Dim newDragValue As Integer = Max
    If (newDragValue <> dragValue) Then
    Dim old As Integer = dragValue
    dragValue = newDragValue
    OptimizedInvalidate(old, dragValue)
    End If
    End If

    Else
    If (dragValue <> Value) Then
    Dim old As Integer = dragValue
    dragValue = Value
    OptimizedInvalidate(old, dragValue)
    End If

    End If

    End If

    End Sub









  3. #3
    nnch97 Guest

    Re: Context menu manipulation


    Thanks a lot for your reply but this is not what I am trying to do. I am actually
    creating a MS Money style menubutton user control, a context menu would be
    assigned to it and properties would be exposed like "MenuAlignment" which
    would be left/right and "MenuDirection" which could be Up/Down. Now based
    on what the user chooses, when this button is clicked run time then I have
    to show the context menu based on the properties specified. Now I am using
    the "Show" method of context menu but the problem is that with it just the
    top left corner of the context menu is configured. So if someone chooses
    alignment as left and direction as top then the show method would be passed
    the point as 0,0 which would start the context menu from the top left edge
    of the button and would thus overlap the button. Instead I need a way to
    either draw the whole menu dynamically or somehow manipulate the location
    of the menu so that the bottom edge of the menu lies on the top edge of the
    button.

    This could be confusing but imagine a simple clickable button which has a
    image pointing up or down at left or right side and when you click on that
    button the context menu shows up.

    Please help.


    "PWilmarth" <pwilmarth80231@msn.com> wrote:
    >
    >If I understand your question correctly:
    >
    >
    >You need to create a rectangle that defines the area where the
    >the context menu is active(or can be shown). Defining this rectangle will
    >be your challenge, but the rectangle will give you X and Y points that you
    >are valid points that can respond to MouseEvents.
    >
    >Then code some MouseEvents(Button1_MouseHover, Button1_MouseEnter, Button1_MouseDown)
    >that handle the event. If the Mouse is within your rectangle, the context
    >menu is active (you could use the Show Method).
    >
    >The following comes from the .NET OnLine Help, but it gives some useful
    >hints about how to attack your problem. It overrides the base class event
    >OnMouseMove.
    >
    > Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
    > SetDragValue(New Point(e.X, e.Y))
    > End Sub
    >
    >Private Sub SetDragValue(ByVal mouseLocation As Point)
    >
    > Dim client As Rectangle = ClientRectangle
    >
    > If (client.Contains(mouseLocation)) Then
    >
    > If (client.Y <= mouseLocation.Y And mouseLocation.Y <=

    client.Y
    >+ client.Height) Then
    > If (mouseLocation.X <= client.X And mouseLocation.X
    >
    >client.X - LeftRightBorder) Then
    > Dim newDragValue As Integer = Min
    > If (newDragValue <> dragValue) Then
    > Dim old As Integer = dragValue
    > dragValue = newDragValue
    > OptimizedInvalidate(old, dragValue)
    > End If
    >
    > ElseIf (mouseLocation.X >= client.X + client.Width And
    >mouseLocation.X < client.X + client.Width + LeftRightBorder) Then
    > Dim newDragValue As Integer = Max
    > If (newDragValue <> dragValue) Then
    > Dim old As Integer = dragValue
    > dragValue = newDragValue
    > OptimizedInvalidate(old, dragValue)
    > End If
    > End If
    >
    > Else
    > If (dragValue <> Value) Then
    > Dim old As Integer = dragValue
    > dragValue = Value
    > OptimizedInvalidate(old, dragValue)
    > End If
    >
    > End If
    >
    > End If
    >
    > End Sub
    >
    >
    >
    >
    >
    >
    >
    >



  4. #4
    PWilmarth Guest

    Re: Context menu manipulation


    It sounds like you need to pass a negative number to the show method. The
    ideal solution would be based on the height of the context menu and you can
    access this property, but I'm not sure that the number passed back to you
    is in pixels. It is definitely an integer (when I played around with this,
    I got 19 for the context menu. You can access this number like this piece
    of code:

    myMenuHeight= System.Windows.Forms.SystemInformation.MenuHeight.ToString

    Now I'm not sure if this is the height for each menu item in your context
    menu or the total height(I suspect it is the menu height for each menu item).

    You are correct that point = (0,0) will align the top left corner of the
    context menu to the top left corner of the button. If you want to align the
    bottom of the context menu to the top of the button, you need to subtract
    the context menu height from 0 (this is the most accurate method for positioning
    the context menu) to create a new Y. You could try something like this:

    dim X as integer = 0
    dim Y as integer = 0
    dim m_Point as Point = new Point(X, Y - System.Windows.Forms.SystemInformation.MenuHeight)
    ContextMenu.Show(Button, m_Point)

    This will move the context menu up, but once again, you may need to make
    some adjustments by multiplying the MenuHeight by the number of menu items
    (I had only one Menu Item in my list.
    When I multiplied the MenuHeight by 1.25, I got a pretty good alignment with
    the bottom of the context menu and the top of the button.

    I haven't been able to ascertain anyway to determine the context menu width,
    but you can also create a negative number based on the button width if you
    need to move the context menu to the left of the button.

    Let me know if this approximates the solution you are looking for. This was
    definitely an interesting problem to think through. If you find another solution
    (or better solution) let me know.

    PW
    >
    >Thanks a lot for your reply but this is not what I am trying to do. I am

    actually
    >creating a MS Money style menubutton user control, a context menu would

    be
    >assigned to it and properties would be exposed like "MenuAlignment" which
    >would be left/right and "MenuDirection" which could be Up/Down. Now based
    >on what the user chooses, when this button is clicked run time then I have
    >to show the context menu based on the properties specified. Now I am using
    >the "Show" method of context menu but the problem is that with it just the
    >top left corner of the context menu is configured. So if someone chooses
    >alignment as left and direction as top then the show method would be passed
    >the point as 0,0 which would start the context menu from the top left edge
    >of the button and would thus overlap the button. Instead I need a way to
    >either draw the whole menu dynamically or somehow manipulate the location
    >of the menu so that the bottom edge of the menu lies on the top edge of

    the
    >button.
    >
    >This could be confusing but imagine a simple clickable button which has

    a
    >image pointing up or down at left or right side and when you click on that
    >button the context menu shows up.
    >
    >Please help.
    >
    >
    >"PWilmarth" <pwilmarth80231@msn.com> wrote:
    >>
    >>If I understand your question correctly:
    >>
    >>
    >>You need to create a rectangle that defines the area where the
    >>the context menu is active(or can be shown). Defining this rectangle will
    >>be your challenge, but the rectangle will give you X and Y points that

    you
    >>are valid points that can respond to MouseEvents.
    >>
    >>Then code some MouseEvents(Button1_MouseHover, Button1_MouseEnter, Button1_MouseDown)
    >>that handle the event. If the Mouse is within your rectangle, the context
    >>menu is active (you could use the Show Method).
    >>
    >>The following comes from the .NET OnLine Help, but it gives some useful
    >>hints about how to attack your problem. It overrides the base class event
    >>OnMouseMove.
    >>
    >> Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
    >> SetDragValue(New Point(e.X, e.Y))
    >> End Sub
    >>
    >>Private Sub SetDragValue(ByVal mouseLocation As Point)
    >>
    >> Dim client As Rectangle = ClientRectangle
    >>
    >> If (client.Contains(mouseLocation)) Then
    >>
    >> If (client.Y <= mouseLocation.Y And mouseLocation.Y <=

    >client.Y
    >>+ client.Height) Then
    >> If (mouseLocation.X <= client.X And mouseLocation.X
    >>
    >>client.X - LeftRightBorder) Then
    >> Dim newDragValue As Integer = Min
    >> If (newDragValue <> dragValue) Then
    >> Dim old As Integer = dragValue
    >> dragValue = newDragValue
    >> OptimizedInvalidate(old, dragValue)
    >> End If
    >>
    >> ElseIf (mouseLocation.X >= client.X + client.Width

    And
    >>mouseLocation.X < client.X + client.Width + LeftRightBorder) Then
    >> Dim newDragValue As Integer = Max
    >> If (newDragValue <> dragValue) Then
    >> Dim old As Integer = dragValue
    >> dragValue = newDragValue
    >> OptimizedInvalidate(old, dragValue)
    >> End If
    >> End If
    >>
    >> Else
    >> If (dragValue <> Value) Then
    >> Dim old As Integer = dragValue
    >> dragValue = Value
    >> OptimizedInvalidate(old, dragValue)
    >> End If
    >>
    >> End If
    >>
    >> End If
    >>
    >> End Sub
    >>
    >>
    >>
    >>
    >>
    >>
    >>
    >>

    >



  5. #5
    PWilmarth Guest

    Re: Context menu manipulation


    I tried this with 3 menu items.

    You do need to multiply the number of menu items in your longest column by
    the menuHeight and then make some adjustments so the bottom of the context
    menu aligns better visually. I found that adding 0.25 or 0.3 (I'm calling
    this "the adjustment factor") to the product makes the context menu line
    up pretty nicely.

  6. #6
    nnch97 Guest

    Re: Context menu manipulation


    Hi,

    Thank you so much for your effort, I was thinking on the same line, I tried
    yesterday with VB5 and came to this formula to get the height on the menu:
    (17 * aMenu.MenuItems.Count) + 4.5. After reading your post today I tried
    using (System.Windows.Forms.SystemInformation.MenuHeight * aMenu.MenuItems.Count)in
    this .net project but this is not getting accurate, I even tried adding .25/.3
    etc. as adjustment factors but they do not seem to work, can you write what
    exact formula you used. Also this and my above formula falls apart when there
    are separators in the menu... any ideas about how to handle that.

    Thank you so much, I really appreciate your help.

    "PWilmarth" <pwilmarth80231@msn.com> wrote:
    >
    >I tried this with 3 menu items.
    >
    >You do need to multiply the number of menu items in your longest column

    by
    >the menuHeight and then make some adjustments so the bottom of the context
    >menu aligns better visually. I found that adding 0.25 or 0.3 (I'm calling
    >this "the adjustment factor") to the product makes the context menu line
    >up pretty nicely.



  7. #7
    Guest

    Re: Context menu manipulation


    Dim X As Integer = 0
    Dim Y As Integer = -1 * (3 * System.Windows.Forms.SystemInformation.MenuHeight
    + 0.3)

    Dim newPoint As Point = New Point(X, Y)

    ContextMenu.Show(Button1, newPoint)

    is the piece of code I use for 3 menu items.

    However, I used your method, and it does adjust the context menu pretty well,
    but I don't know how precise you want to be in the location of your context
    menu. I found that you need to adjust the context menu by 7 or 8 for each
    separator in you list (Don't count the separotors as menu Items, they are
    smaller than one MenuItem). I have some thoughts about why this may be
    and I think it has to do with the height of the border lines for the context
    menu, plus some additional space between the last item in the menu and the
    border (border height returns as 1).

    PW


    "nnch97" <vb.@127.0.0.1> wrote:
    >
    >Hi,
    >
    >Thank you so much for your effort, I was thinking on the same line, I tried
    >yesterday with VB5 and came to this formula to get the height on the menu:
    >(17 * aMenu.MenuItems.Count) + 4.5. After reading your post today I tried
    >using (System.Windows.Forms.SystemInformation.MenuHeight * aMenu.MenuItems.Count)in
    >this .net project but this is not getting accurate, I even tried adding

    .25/.3
    >etc. as adjustment factors but they do not seem to work, can you write what
    >exact formula you used. Also this and my above formula falls apart when

    there
    >are separators in the menu... any ideas about how to handle that.
    >
    >Thank you so much, I really appreciate your help.
    >
    >"PWilmarth" <pwilmarth80231@msn.com> wrote:
    >>
    >>I tried this with 3 menu items.
    >>
    >>You do need to multiply the number of menu items in your longest column

    >by
    >>the menuHeight and then make some adjustments so the bottom of the context
    >>menu aligns better visually. I found that adding 0.25 or 0.3 (I'm calling
    >>this "the adjustment factor") to the product makes the context menu line
    >>up pretty nicely.

    >



  8. #8
    PWilmarth Guest

    Re: Context menu manipulation


    Dim X As Integer = 0
    Dim Y As Integer = -1 * (Number of Menu Items * System.Windows.Forms.SystemInformation.MenuHeight
    + 7.5 * Number of Separators)
    Dim m_Point as Point = New Point(X, Y)
    ContextMenu.Show(button, m_Point)

    Is the precise code I used, but once again, I don't know how precise you
    need to be in locating the bottom of your context menu.

    PW

  9. #9
    Guest

    Re: Context menu manipulation


    Ok, Thank you so much for your help.


    "PWilmarth" <pwilmarth80231@msn.com> wrote:
    >
    > Dim X As Integer = 0
    > Dim Y As Integer = -1 * (Number of Menu Items * System.Windows.Forms.SystemInformation.MenuHeight
    >+ 7.5 * Number of Separators)
    >Dim m_Point as Point = New Point(X, Y)
    >ContextMenu.Show(button, m_Point)
    >
    >Is the precise code I used, but once again, I don't know how precise you
    >need to be in locating the bottom of your context menu.
    >
    >PW



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center