Olivarsham
Olivarsham

Reputation: 1731

Set the content of Label to Image's Tooltip

I am using IValueconverter interface to change the tooltip text of an image.
The tool tip should change based on label.

<Label Content="9898980001" Height="28" HorizontalAlignment="Left" Margin="1733,231,0,0" Name="lbl02scanning" VerticalAlignment="Top" Foreground="Blue" >

<Image Height="49" HorizontalAlignment="Right" Margin="0,131,113,0" 
       Name="img02scanning"
       Source="/TEST;component/Images/LoadingStation.png" Stretch="Fill" 
       VerticalAlignment="Top" Width="30" Cursor="Hand">
    <Image.ToolTip>
        <StackPanel Background="AliceBlue">
            <TextBlock Padding="5" Foreground="White" MinHeight="20"
                       Background="Blue" FontWeight="Bold" 
                       Text="Scanning Station" />
             <StackPanel Orientation="Horizontal">
                <Image 
   Source="pack://application:,,,/TEST;component/Images/coilonsaddle_large.png" 
   Height="100" Width="100" />
                 <TextBlock Padding="10" TextWrapping="WrapWithOverflow"
                            MaxWidth="200" Background="AliceBlue"
                            Foreground="Black" FontWeight="Bold"
                            Text="{Binding ElementName=lbl02scanning, Path=Name, 
                                           ConverterParameter=255,
                             Converter={StaticResource FormatterFOrCoilToolTip}}"/>                                       
              </StackPanel>
              <TextBlock Padding="5" Foreground="White" MinHeight="20" 
                         Background="Blue" FontWeight="Bold"
                         Text="Report to admin in case of coil location mismatch"/>
         </StackPanel>
    </Image.ToolTip>  
</Image>

The converter class:

 public class FormatterForCoilToolTip : IValueConverter
    {

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {

      if(parameter.ToString() == "02")
      {
      return value.ToString() + " Startin";
      }
      else
      {
      return value.ToString() + " Finishing";
          }
    }


    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

The tooltip's Textblock content is not changing. But if i change to:

Text="{Binding  ConverterParameter=255, Converter={StaticResource FormatterFOrCoilToolTip}}

then it is working. But i want to pass the lbl02scanning text value. Why it is not working??

Upvotes: 0

Views: 416

Answers (2)

Rohit Vats
Rohit Vats

Reputation: 81348

First of all you should bind to Content property and not Name property in case you want Text of Label.

Most importantly Tooltip does not lies in same Visual Tree as that of label, hence binding with elementName won't work. However, you can use x:Reference to get the element even if it doesn't exist in same Visual Tree.

Text="{Binding Source={x:Reference lbl02scanning}, Path=Content, 
               ConverterParameter=255,
               Converter={StaticResource FormatterFOrCoilToolTip}}"/>

Note - x:Reference is introduced in WPF 4.0. If you are using WPF 3.5 you can't use this.


Update for error - service provider is missing the name resolver service

Just found out bug is reported at Microsoft site that x:Reference fails in case Target is Label. However, i couldn't reproduce this issue at my end since i have WPF 4.5 installed at my end and i guess they have fixed the issue in future version.

In case you target WPF 4.0, i would advise you to use TextBlock in place of Label:

<TextBlock Text="9898980001" Height="28" HorizontalAlignment="Left"
           Margin="1733,231,0,0" Name="lbl02scanning" VerticalAlignment="Top" 
           Foreground="Blue" />

and then bind with Text property instead of Content.

Text="{Binding Source={x:Reference lbl02scanning}, Path=Text, 
               ConverterParameter=255,
               Converter={StaticResource FormatterFOrCoilToolTip}}"/>

Either, you can refer to workaround provide under workarounds section here.

You can override the ProvideValue method of the Reference class and skip the reference search login in design time:

[ContentProperty("Name")]
public class Reference : System.Windows.Markup.Reference
{
    public Reference()
        : base()
    { }

    public Reference(string name)
        : base(name)
    { }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        IProvideValueTarget valueTargetProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;

        if (valueTargetProvider != null)
        {
            DependencyObject targetObject = valueTargetProvider.TargetObject as DependencyObject;

            if (targetObject != null && DesignerProperties.GetIsInDesignMode(targetObject))
            {
                 return null;
            }
        }

        return base.ProvideValue(serviceProvider);
    }

Update with another workaround

This will work for all versions WPF 3.5, WPf 4.0 and WPF 4.5.

First of all bind Image Tag with content of label.

Second host your stackPanel inside ToolTip control so that you can take benefit of PlacementTarget property.

Third bind with PlacementTarget.Tag of Tooltip.

Relevant code will look like this:

<Image Tag="{Binding ElementName=lbl02scanning,Path=Content}">
   <Image.ToolTip>
      <ToolTip>
          <TextBlock Text="{Binding RelativeSource={RelativeSource 
                                    Mode=FindAncestor, AncestorType=ToolTip},
                                    Path=PlacementTarget.Tag,
                                    ConverterParameter=255,
                           Converter={StaticResource FormatterFOrCoilToolTip}}"/>
       </ToolTip>
   </Image.ToolTip>
</Image>

Also you need to update converter code to put null check over there since PlacementTarget will be null until you open tooltip.

    public object Convert(object value, Type targetType,
                          object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            if (parameter.ToString() == "02")
            {
                return value.ToString() + " Starting";
            }
            else
            {
                return value.ToString() + " Finishing";
            }
        }
        return String.Empty;
    }

Upvotes: 2

mohammad jannesary
mohammad jannesary

Reputation: 1821

Try This

Text="{Binding Path=Content,ElementName=lbl02scanning, ConverterParameter=255, Converter={StaticResource FormatterFOrCoilToolTip}}

Upvotes: 0

Related Questions