none
Why is there different behaviors between ListViewItem ToolTipText for .NET 3.5 and 4.0?

    Question

  • Take a simple example from:

    http://msdn.microsoft.com/en-us/library/system.windows.forms.listviewitem.tooltiptext%28v=vs.80%29.aspx

    Add a couple lines to it:

    this.toolTip1 = new System.Windows.Forms.ToolTip();
    this.toolTip1.SetToolTip(ListViewWithToolTips, "Left blank on purpose, until items are added.");

    And when the target framework is .NET 4 the Tooltips don't show on the listview.
    When the target framework is .NET 3.5 the Tooltips do show up.

    I've reproduced this on multiple different machines.
    All machines have the latest patches/updates installed.

    Resulting Sample C# code looks like:

    // Declare the ListView.
    private ListView ListViewWithToolTips;
    // Declare the ToolTip
    private ToolTip toolTip1;

    private void InitializeItemsWithToolTips()
    {

        // Construct and set the View property of the ListView.
        ListViewWithToolTips = new ListView();
        ListViewWithToolTips.Width = 200;
        ListViewWithToolTips.View = View.List;

        // Show item tooltips.
        ListViewWithToolTips.ShowItemToolTips = true;
       
        // These two new lines work fine when targeted as .NET 3.5
        this.toolTip1 = new System.Windows.Forms.ToolTip();
        this.toolTip1.SetToolTip(ListViewWithToolTips, "Left blank on purpose, until populated later.");
       
        // Create items with a tooltip.
        ListViewItem item1WithToolTip = new ListViewItem("Item with a tooltip");
        item1WithToolTip.ToolTipText = "This is the item tooltip.";
        ListViewItem item2WithToolTip = new ListViewItem("Second item with a tooltip");
        item2WithToolTip.ToolTipText = "A different tooltip for this item.";

        // Create an item without a tooltip.
        ListViewItem itemWithoutToolTip = new ListViewItem("Item without tooltip.");

        // Add the items to the ListView.
        ListViewWithToolTips.Items.AddRange(new ListViewItem[]{item1WithToolTip,
            item2WithToolTip, itemWithoutToolTip} );

        // Add the ListView to the form.
        this.Controls.Add(ListViewWithToolTips);
        this.Controls.Add(button1);
    }

     

    • Moved by eryang Thursday, May 05, 2011 6:14 AM (From:.NET Base Class Library)
    Wednesday, May 04, 2011 3:56 PM

Answers

  •  

     

    Tooltip calls back into the owner control to do the job, in this case, it calls back into ListView.SetToolTip.

    Tooltip.cs:

           private void CheckNativeToolTip(Control associatedControl) {

    <snip>

               if (associatedControl is ListView) {

                   ((ListView)associatedControl).SetToolTip(this, GetToolTip(associatedControl));

                }

    ListView.cs:

           /// <include file='doc\ListView.uex' path='docs/doc[@for="ListView.SetToolTip"]/*' /> 

            /// <devdoc> 

            ///     Called by ToolTip to poke in that Tooltip into this ComCtl so that the Native ChildToolTip is not exposed. 

            /// </devdoc> 

            /// <internalonly/>

            internal void SetToolTip(ToolTip toolTip, string toolTipCaption) {

                this.toolTipCaption = toolTipCaption;

                //native ListView expects tooltip HWND as a wParam and ignores lParam

                IntPtr oldHandle = UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.LVM_SETTOOLTIPS, new HandleRef(toolTip, toolTip.Handle), 0);

                UnsafeNativeMethods.DestroyWindow(new HandleRef(null, oldHandle));

            }

    The yellow line is how it should be. In Orcas it was:

    UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.LVM_SETTOOLTIPS, new HandleRef(toolTip, toolTip.Handle), 0);

    We have fixed a leak in listview tooltip in before version:

    Tooltip handle leak with an extended listview control

    Like this:

    IntPtr oldHandle = UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.LVM_SETTOOLTIPS, 0, new HandleRef(toolTip, toolTip.Handle));

    UnsafeNativeMethods.DestroyWindow(new HandleRef(null, oldHandle));

    By adding the destroywindow call after the SendMessage. And in an attempt to improve code (my speculation) we swapped wParam and lParam! This actually broke tooltips on the listview (you can’t attach a single tooltip to the whole listview in 4.0 any longer), not just the scenario you pointed out…. 

     

     

    So we can Send the correct message like above said after we use the SetToolTip method.

    http://www.pinvoke.net/default.aspx/user32.sendmessage

    You can ref this document to do p/invoke the win32 API SendMessage to send message to set the tooltip.

     

    If there's any concern, please feel free to let us know.

    Best wishes,


    Mike [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.



    • Marked as answer by kstudent Friday, May 13, 2011 2:00 PM
    Thursday, May 12, 2011 5:44 AM
    Moderator

All replies

  • Move to winform forum for better support.
    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, May 05, 2011 6:13 AM
  • Hi,

    They should act the same, so even if we find out that you are rigth, it does not help you.

    Try to connect to Microsoft direct for this behaviour.

    http://connect.Microsoft.Com

     


    Success
    Cor
    Thursday, May 05, 2011 6:50 AM
  • Hi kstudent,

    I see this issue.

    And I also try to monitor the properties, but I have not found anything unexpected.

    I think you can submit this issue to the MS Connect as Cor suggested.

    I will post the reply if I have any update after more research.

     

    Best wishes,


    Mike [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, May 05, 2011 12:35 PM
    Moderator
  • I've created a bug report via http://connect.Microsoft.Com
    (as Mike and Cor suggested)

    Here is the link:
    https://connect.microsoft.com/VisualStudio/feedback/details/667101/

     

    Thanks again.

    Friday, May 06, 2011 2:12 PM
  • Thanks for shraing this feedback.
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, May 09, 2011 4:06 PM
    Moderator
  •  

     

    Tooltip calls back into the owner control to do the job, in this case, it calls back into ListView.SetToolTip.

    Tooltip.cs:

           private void CheckNativeToolTip(Control associatedControl) {

    <snip>

               if (associatedControl is ListView) {

                   ((ListView)associatedControl).SetToolTip(this, GetToolTip(associatedControl));

                }

    ListView.cs:

           /// <include file='doc\ListView.uex' path='docs/doc[@for="ListView.SetToolTip"]/*' /> 

            /// <devdoc> 

            ///     Called by ToolTip to poke in that Tooltip into this ComCtl so that the Native ChildToolTip is not exposed. 

            /// </devdoc> 

            /// <internalonly/>

            internal void SetToolTip(ToolTip toolTip, string toolTipCaption) {

                this.toolTipCaption = toolTipCaption;

                //native ListView expects tooltip HWND as a wParam and ignores lParam

                IntPtr oldHandle = UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.LVM_SETTOOLTIPS, new HandleRef(toolTip, toolTip.Handle), 0);

                UnsafeNativeMethods.DestroyWindow(new HandleRef(null, oldHandle));

            }

    The yellow line is how it should be. In Orcas it was:

    UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.LVM_SETTOOLTIPS, new HandleRef(toolTip, toolTip.Handle), 0);

    We have fixed a leak in listview tooltip in before version:

    Tooltip handle leak with an extended listview control

    Like this:

    IntPtr oldHandle = UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.LVM_SETTOOLTIPS, 0, new HandleRef(toolTip, toolTip.Handle));

    UnsafeNativeMethods.DestroyWindow(new HandleRef(null, oldHandle));

    By adding the destroywindow call after the SendMessage. And in an attempt to improve code (my speculation) we swapped wParam and lParam! This actually broke tooltips on the listview (you can’t attach a single tooltip to the whole listview in 4.0 any longer), not just the scenario you pointed out…. 

     

     

    So we can Send the correct message like above said after we use the SetToolTip method.

    http://www.pinvoke.net/default.aspx/user32.sendmessage

    You can ref this document to do p/invoke the win32 API SendMessage to send message to set the tooltip.

     

    If there's any concern, please feel free to let us know.

    Best wishes,


    Mike [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.



    • Marked as answer by kstudent Friday, May 13, 2011 2:00 PM
    Thursday, May 12, 2011 5:44 AM
    Moderator