WPF Image Tooltip - wpf

I have a tooltip on an image inside of a listbox. The tooltip is setup as follows:
<Image Grid.Column="0" Source="{Binding PingRankImage}"
Width="16" Height="16"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Image.ToolTip>
<ToolTip Content="{Binding Ping, StringFormat='Ping: {0}ms'}"
ContentStringFormat="{}Ping: {0}ms}" />
</Image.ToolTip>
</Image>
but the tooltip just displays the value and not the 'Ping: XXXms'
Any ideas?

You don't need extra {} prefix in ContentStringFormat. With ToolTip, also prefer using ContentStringFormat instead of StringFormat in binding.
Following works:
<Image.ToolTip>
<ToolTip Content="{Binding}"
ContentStringFormat="Ping: {0}ms" />
</Image.ToolTip>

Related

Showing download percentage with xaml

I am trying to figure out a way to show the user the download progress like this:
17.38/50Mb's
But I need to bidnd through xaml with StringFormat
To use StringFormat in XAML,
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DownloadSizeInMB, StringFormat={0:0.00}}" />
<TextBlock Text="/" />
<TextBlock Text="{Binding TotalSizeInMB, StringFormat={0:0.00}}" />
<TextBlock Text="Mb's" />
</StackPanel>
But these comes with some Margin between the TextBlocks.
I would suggest you use MultiBinding instead.

Canvas position based on another element

Basically I want a Canvas to act like a StackPanel. So how do set the Canvas.Top="" based on Canvas.Bottom of another element?
Background: Trying to make an Expander that when expanded it will go over other elements. Figured using a Canvas ZIndex would be the best way to do this. So I created this:
<StackPanel Orientation="Vertical" >
<Canvas Height="{Binding ActualHeight, ElementName=MyExpander}">
<Expander Panel.ZIndex="1" Name="MyExpander" Header="Header" >
<StackPanel Background="LightGray">
<TextBlock Text="Some text" />
<TextBlock Text="Some text" />
<TextBlock Text="Some text" />
<TextBlock Text="Some text" />
<TextBlock Text="Some text" />
<TextBlock Text="Some text" />
</StackPanel>
</Expander>
<StackPanel Panel.ZIndex="0" Canvas.Top="20" Margin="0,5,0,0">
<Button Content="Button1" />
<Button Content="Button2" />
<Button Content="Button3" />
</StackPanel>
</Canvas>
</StackPanel>
Now this works perfectly the problem is that Canvas.Top="20" is hardcoded into the XAML. So that means if the font gets increased (the user increased font sizing in Windows) then part of the StackPanel will be under the Expander. I tried this:
Canvas.Bottom="{Binding (Canvas.Bottom),ElementName=MyExpander}"
The issue being is that value for for Canvas.Bottom for MyExpander is NaN so that isn't going to work.
FYI if there is a better way to do the Expander expands over top of elements I am open to that as well.
thanks
Well this doesn't seem like the greatest answer but it worked for me.
foreach (var exp in MyCanvas.Children)
{
Expander ep = (Expander)exp;
double h = ep.ActualHeight;
Canvas.SetTop(ep, y);
y = y + h + 20;
}
Should note it goes without saying that foreach loop is a bit more complicated due to correct parsing of the objects in the MyCanvas

WPF Tooltip binding and open programatically does not work

I have a Custom tooltip icon which also has its content bound to Datacontext. My need was to open Tooltop on mouse hover as well as on click event. So I used following code
<Image Source="/MainUI;component\Images\home\tooltip_info.png"
Width="24" Height="24" Stretch="Fill" HorizontalAlignment="Right"
Name="ImageToolTip"
Margin="0,0,0,0" MouseUp="ImageToolTip_MouseUp" MouseLeave="ImageToolTip_MouseLeave">
<Image.ToolTip>
<ToolTip BorderBrush="Transparent" Background="Transparent" HorizontalOffset="-142">
<TextBlock TextWrapping="WrapWithOverflow"
Style="{StaticResource ExcalFont-MSFD300}"
FontSize="14" Text="{Binding Tips}"
Width="300" Padding="15,15,15,15">
<TextBlock.Background>
<ImageBrush ImageSource="Images\home\popupbox.png" />
</TextBlock.Background>
</TextBlock>
</ToolTip>
</Image.ToolTip>
</Image>
Code Behind:
private void ImageToolTip_MouseUp(object sender, MouseButtonEventArgs e)
{
((ToolTip)((FrameworkElement)sender).ToolTip).IsOpen = true;
}
private void ImageToolTip_MouseLeave(object sender, MouseEventArgs e)
{
((ToolTip)((FrameworkElement)sender).ToolTip).IsOpen = false;
}
Now the issue is on mouse up It opens Tooltip but it does not bind the text.
This is working fine if I am using static text instead of Binding. What am I doing wrong?
In case I mouse hover on icon then it works fine and shows the content too. Thereafter everytime mouse click also shows the tooltip content. Not sure why mouse click do not work initially. –
ToolTip is not part of the VisualTree.
A problem that is similar to the problem you have is described here:
RelativeSource binding from a ToolTip or ContextMenu
One option to solve your problem would be something like this:
<Image Source="/MainUI;component\Images\home\tooltip_info.png"
Width="24" Height="24" Stretch="Fill" HorizontalAlignment="Left"
Name="ImageToolTip"
Margin="0,0,0,0" MouseUp="ImageToolTip_MouseUp" MouseLeave="ImageToolTip_MouseLeave" Tag="{Binding DataContext,RelativeSource={RelativeSource Mode=Self}}">
<Image.ToolTip>
<ToolTip BorderBrush="Transparent" Background="Transparent" HorizontalOffset="-142" >
<TextBlock TextWrapping="WrapWithOverflow"
FontSize="14" Text="{Binding PlacementTarget.Tag.Tips,
RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ToolTip}}"
Width="300" Padding="15,15,15,15">
<TextBlock.Background>
<ImageBrush ImageSource="Images\home\popupbox.png" />
</TextBlock.Background>
</TextBlock>
</ToolTip>
</Image.ToolTip>
</Image>

WPF Dockpanel won't align right

I have this code on which I use a DockPanel on a Button.Content. However it doesn't let me right align the last image (small arrow).
<Button Height="70"
HorizontalContentAlignment="Left">
<Button.Content>
<DockPanel LastChildFill="False">
<Image DockPanel.Dock="Left"
Height="50"
Width="50"
Source="{StaticResource Placeholder}"
Stretch="UniformToFill"
Margin="5" />
<TextBlock DockPanel.Dock="Left"
Text="Dummy text"
VerticalAlignment="Center"
Margin="5" />
<Image DockPanel.Dock="Right"
Height="24"
Width="24"
Source="{StaticResource Right_Arrow_24}"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Stretch="UniformToFill"
Margin="5" />
</DockPanel>
</Button.Content>
</Button>
It now gives me this:
So the right small arrow should be placed on the right of the button and not just after the TextBlock.
I've found some similar issues and it looks like I did it correct, but somehow it isn't..
What am I doing wrong here?
Try to set the HorizontalContentAlignment of your button to "Stretch". Otherwise your DockPanel will use the size need by its content, then align left. You can confirm this behaviour by using different text lengths for your TextBlocks
You simply have to append an extra child to the DockPanel (say an empty Canvas) without the DockPanel.Dock attribute, so that all the remaining space is assigned to it.
In general, DockPanel only works fine only when its last child has no Dock constraint
Try setting
HorizontalContentAlignment="Stretch"
On your button.

Specifying a Button Content that has mix of text and a Binding path

How do you specify the Content of a button that is a mix of some TEXT and a Binding path?
Like this:
<Button Content= "TEXT" + "{Binding Path=ButtonContent}"
For most cases you can use StringFormat in the Bindings, like for a TextBlock
<TextBlock Text="{Binding ElementName=textBox,
Path=Text,
StringFormat='{}{0} - Added Text'}"/>
However, this has no effect on a ContentControl (which Button inherits from). Instead, you can use ContentStringFormat
<Button Content="{Binding ElementName=textBox,
Path=Text}"
ContentStringFormat="{}{0} - Added Text"/>
Also, for
ContentControl you use ContentStringFormat
HeaderedContentControl you use HeaderStringFormat
ItemsControl you use ItemStringFormat
Something like this:
<Button>
<Button.Content>
<TextBlock Text="{Binding SomeBindingPath, StringFormat='Some text {0}'}"/>
</Button.Content>
</Button>
OR
<Button>
<Button.Content>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Some Text"/>
<TextBlock Text="{Binding SomeBindingPath}"/>
</StackPanel>
</Button.Content>
</Button>
Basically, you can put any content inside a button using the approach above.
Building on the other answers, this is a little more terse:
<Button Content="{Binding FirstName, StringFormat='Click here, {0}!'}" />

Resources