views:

1039

answers:

1

I am using DataTemplates to render items in an ItemsControl. I want to show a tooltip for each item. If I use a binding such as ToolTip="{Binding MyToolTip,Mode=OneWay}", WPF gets the tooltip once at the beginning and does not update the tooltip when it is opened.

My items implement INotifyPropertyChanged, so in principle I could generate change notifications for MyToolTip. The problem is, the tooltip is produced based on many pieces of information in the underlying model. These pieces of information change frequently and it would be both cumbersome and inefficient to generate change notifications for the MyToolTip property. Besides, I do not want tooltips for ALL items to be produced initially. Instead I would like to force a fresh tooltip to be generated when the tooltip is opened. How can I do it?

+1  A: 

You will have to use a little code-behind, but it isn't that bad.

<object ToolTip="{Binding MyToolTip, Mode=OneWay}" ToolTipOpening="MyToolTip_Opening" />

In code-behind

private void MyToolTip_Opening(object sender, ToolTipEventArgs e)
{
    DependencyObject depObj = sender as DependencyObject;
    if (depObj == null) return;
    BindingExpression be = BindingOperations.GetBindingExpression(depObj, FrameworkElement.ToolTipProperty);
    if (be != null) be.UpdateTarget();
}
Bryce Kahle
I'm assuming that somewhere before you call update on the BindingExpression, you'd be updating the ToolTip text?
micahtan
He said that it would be cumbersome to generate change notifications, but I guess I was still assuming that the MyToolTip property was still the correct way to obtain the tooltip. Calling BindingExpression.UpdateTarget() will requery that property for its value.
Bryce Kahle
At that point, I think you could probably also add UpdateSourceTrigger=Explicit to the binding expression, and save the overhead of populating the ToolTip when the control is first populated.
Joe White
UpdateSourceTrigger only affects the propagation of changes from the target to the source. Since this is a OneWay binding, those changes are ignored anyways.
Bryce Kahle
Thanks, that worked like a charm! Joe White's tip didn't work though--I think UpdateSourceTrigger=Explicit means that changes to the WPF control don't propagate back to the data source automatically. So if Mode=OneWay then UpdateSourceTrigger=Explicit has no effect.
Qwertie
I was surprised to learn that it's actually possible to attach an event handler inside a DataTemplate in my UserControl's Resources. What if the resources are in an independent shared dictionary, does that make it impossible to attach event handlers?
Qwertie