0

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!

Jake Smith
  • 2,332
  • 1
  • 30
  • 68

2 Answers2

2

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;
}
nempoBu4
  • 6,521
  • 8
  • 35
  • 40
  • This works great. And makes complete sense. Not sure why I felt comfortable binding to the `EditValue`/`Text`/`Value` properties and not the `ToolTip` property. Thank you much. – Jake Smith Jul 23 '14 at 15:18
  • If you wouldn't mind a follow up question: upon using your first suggestion with all the controls in my `LayoutControl`, only the `LookUpEdit` controls seem to have this odd behavior: they always fail validation. I don't have any validation rules that I've specified myself, but as soon as I remove the binding to those controls' ToolTip properties, they no longer fail validation...Any ideas? – Jake Smith Jul 23 '14 at 19:08
  • @JakeSmith I cannot reproduce this behaviour. I have updated my answer, I think is better to use `DataSourceUpdateMode.Never` mode for `ToolTip` property: `devExpressControl.DataBindings.Add(new Binding("ToolTip", dataFeatures, "Key", true, DataSourceUpdateMode.Never));`. Maybe it can help you. – nempoBu4 Jul 24 '14 at 06:02
  • Thank you @nempoBu4! This definitely looks like my issue is resolved. I read up a little bit on this enum: `Data source is never updated and values entered into the control are not parsed, validated or re-formatted.` Is this just saying it won't parse and validate the ToolTip property? Or does this mean my control avoid validation all together? Right now, that is perfectly fine either way, but I may need validation later on for the actual value assigned to the control's EditValue. Thanks again for your help, it is much appreciated... – Jake Smith Jul 24 '14 at 15:58
  • 1
    @JakeSmith Yes, it won't parse and validate only the `ToolTip` property. All other properties will be validated, because the default option is `DataSourceUpdateMode.OnValidation`. – nempoBu4 Jul 25 '14 at 03:57
0

You can easily implement dynamic tooltips with the ToolTipController component. Put this component onto the Form, and assign to each editor via the BaseControl.ToolTipController property.

When it is done, you can handle the ToolTipController.BeforeShow event and change the text according to the control state. The active control is passed through the SelectedControl property of the event parameter.

Uranus
  • 1,690
  • 1
  • 12
  • 22
  • I have tried what you suggested and the `BeforeShow` event is not firing. All controls are indeed in a `LayoutControl` – Jake Smith Jul 21 '14 at 15:54
  • It was my mistake thinking that controls inherit the ToolTipController from the LayoutControl. It is true for the StyleController component, but not for the ToolTipController. If you assign a ToolTipController to each editor and set any value to the editor's ToolTip property, it will raise the BeforeShow event before displaying the tooltip. – Uranus Jul 22 '14 at 06:05
  • Oh okay, no worries. I tried testing this out on one of the controls, and for whatever reason, it still was not firing the BeforeShow event. I'm going to attempt @nempoBu4's answer to see how that goes really quick. I really appreciate your efforts though! – Jake Smith Jul 22 '14 at 22:40