Search code examples
winformsbindingdevexpresstooltipdevexpress-windows-ui

dynamic tooltips on Winforms controls


I am looking for the cleanest way to bind the same datasource to a control's tooltip that I am binding to the control itself. For example, I have the line

control.DataBindings.Add(new Binding("EditValue", dataFeatures, "Key", true));

where dataFeatures is of type BindingSource. I repeat similar lines for many controls on a WinForm Form. Some of these controls can adopt values whose text can span a greater text width than what is visible within the control itself. Instead of redesigning the layout of the form to account for the possibility of partially hidden text in some controls in a few situations, I would like to have the tooltip of each control be bound to the same property of the BindingSource as the controls' EditValue or Text property. Is this possible? I can imagine there is a way to do it by hand by handling the EditValueChanged event like I already do for different reasons, but I was hoping there would be a cleaner solution than having to add new lines of code for each control.

Anybody have a suggestion?

Thanks!


Solution

  • 0. For DevExpress controls you can just bind DevExpressControl.ToolTip property to the same value:

    devExpressControl.DataBindings.Add(new Binding("EditValue", dataFeatures, "Key", true));
    devExpressControl.DataBindings.Add(new Binding("ToolTip", dataFeatures, "Key", true, DataSourceUpdateMode.Never));
    


    1. For standard WinForms controls you can use System.Windows.Forms.ToolTip component and its ToolTip.Popup event. For each control set its ToolTip to some value otherwise ToolTip will never appears:

    control.DataBindings.Add(new Binding("Text", dataFeatures, "Key", true));
    toolTip1.SetToolTip(control, "Some value");
    

    Now you can use ToolTip.Popup event:

    private bool _updatingToolTip;
    
    private void toolTip1_Popup(object sender, PopupEventArgs e)
    {
        if (_updatingToolTip) return;
    
        //Get binding for Text property.
        var binding = e.AssociatedControl.DataBindings["Text"];
    
        if (binding == null) return;
    
        //Get binding value.
        var manager = binding.BindingManagerBase;
        var itemProperty = manager.GetItemProperties().Find(binding.BindingMemberInfo.BindingField, true);
    
        object value = itemProperty.GetValue(manager.Current);
        string toolTipText;
    
        if (value == null || string.IsNullOrEmpty(toolTipText = value.ToString()))
        {
            e.Cancel = true;
    
            return;
        }
    
        //Update ToolTip text.
        _updatingToolTip = true;
        toolTip1.SetToolTip(e.AssociatedControl, toolTipText);
        _updatingToolTip = false;
    }