Reputation: 1731
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
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
Reputation: 1821
Try This
Text="{Binding Path=Content,ElementName=lbl02scanning, ConverterParameter=255, Converter={StaticResource FormatterFOrCoilToolTip}}
Upvotes: 0