简体   繁体   中英

WPF - Trouble binding ToolTip text on custom user control

I'm in the process of creating a simple user control; just an ImageButton.

I've already successfully bound the Image to the button and so I've decided to add a tooltip. Now I'm having troubles. It seems that I can hard-code the text for the tooltip in the XAML for the control, but when it's bound it's returning an empty string.

Here's the XAML for my control:

<Button x:Class="BCOCB.DACMS.Controls.ImageButton"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
        Name="this"
        Style="{StaticResource DisabledButton}">

    <Image Source="{Binding ElementName=this, Path=Source}" />    
    <Button.ToolTip>
        <TextBlock Text="{Binding ElementName=this, Path=ToolTipText}" />
    </Button.ToolTip>
</Button>

And here's the dependency property info for the tooltip text:

public static readonly DependencyProperty ToolTipTextProperty = DependencyProperty.Register("ToolTipText", typeof(string), typeof(ImageButton));
public string ToolTipText
{
  get
  {
    return this.GetValue(ToolTipTextProperty) as string;
  }
  set
  {
    this.SetValue(ToolTipTextProperty, value);
  }
}

And, finally, the declaration of the control in my Window:

<controls:ImageButton x:Name="btnAdd" Source="/DACMS;component/Resources/plus.png" ToolTipText="Add New Item" Click="btnAdd_Click" />

As I mentioned before, the image binds just fine and I've done it in exactly the same manner.

Any ideas?

Thanks,
Sonny

EDIT: I have it working now. I've removed the ElementName from the binding and set the TextBlock's DataContext = this in the code behind on instanciation. Still, I'd like to know how to fix this in the XAML, instead.

I'm unable to test this right now, but you can try:

<Button.ToolTip
      DataContext=”{Binding Path=PlacementTarget.Parent.Parent,
                    RelativeSource={x:Static RelativeSource.Self}}"
>
    <TextBlock Text="{Binding Path=ToolTipText}" />
</Button.ToolTip>

You may have to experiment a little with the number of "Parent" in PlacementTarget.

Hopefully this works. I don't like giving answers that I haven't tested, but I don't have VS on this computer. :)

I've had this same problem with binding to a ContextMenu. After my research I think that it is because the ToolTip and ContextMenu do not exist within the visual tree of your page/window/control. And therefore the DataContext is not inherited and makes binding troublesome.

Here is a Xaml hack I found that worked for me.

Binding to a MenuItem in a WPF Context Menu

The way to set the data context to "this" through xaml looks like this:

<Control DataContext={Binding RelativeSource={RelativeSource Self}}>

As another point, wpf buttons allow their content to be just about any (single) thing you want. If you want something other than text (ie, text and an image), it looks like this:

<Button Name="SampleButton" Click="SampleButton_Click">
    <Grid Width="70" Height="62">
        <Label Content="SampleText"/>
        <Image Margin="3,3,3,3" Source="Graphics/sample.ico"/>
    </Grid>
</Button>

This fixes the Problem with the Tooltip Bindings and Dependencies Properties:

<UserControl x:Class="Extended.InputControls.TextBoxUserControl" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:Extended.InputControls"
    x:Name="UserControl"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <TextBox x:Name="textBox">
        <TextBox.ToolTip>
            <ToolTip Content="{Binding Path=CustomToolTip}" Background="Yellow"/>
        </TextBox.ToolTip>
    </TextBox>
</UserControl>

Instead of this ( doesnt Work ):

<UserControl x:Class="Extended.InputControls.TextBoxUserControl" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:Extended.InputControls"
    x:Name="UserControl">
    <TextBox x:Name="textBox">
        <TextBox.ToolTip>
            <ToolTip Content="{Binding ElementName=UserControl, Path=CustomToolTip}" Background="Yellow"/>
        </TextBox.ToolTip>
    </TextBox>
</UserControl>

Since you aren't changing anything but the Text on the tooltip TextBlock you can just use an inline declaration which will generate the TextBlock for you and doesn't require any hacking to get around the name scoping issue you're running into otherwise:

<Button ... ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=ToolTipText}">...

You could alternately set the ToolTip on the Image and use the control as the DataContext, which gets around the name scoping problem. The DataContext will be passed to the ToolTip, allowing normal binding:

<Image DataContext="{Binding ElementName=this}" Source="{Binding Source}">
    <Image.ToolTip>
        <TextBlock FontSize="18" Text="{Binding Path=ToolTipText}" />
    </Image.ToolTip>
</Image>

This way allows additional settings on the TextBlock or more complex visuals.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM