WPF - Tooltip Databinding not working when setting IsOpen=true - c#

I have a button which has a ToolTip attached to it.
There are data-bound information inside the ToolTip.
I am displaying the ToolTip on click as well as on MouseOver.
By using the code:
private void Button_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
tt = btn.ToolTip as ToolTip;
tt.IsOpen = true;
}
If I click the button, the ToolTip is displayed, but without the data-values.
But if I hover the mouse over the button, it displays correctly.
Important
If I hover over it first, get the tooltip, take the mouse away and then come again and click, it displays correctly.
So I'm guessing that I need to do some kind of call for the tooltip to get the databound info when I call the tt.IsOpen = true
How can I achieve the complete display of tooltip by manually calling it?
Thanks in advance.
Update
The xaml code.
<Button Content="{x:Static prop:strings.Info}" Margin="2" HorizontalAlignment="Center" Click="Button_Click" >
<Button.ToolTip>
<ToolTip>
<ToolTip.Template>
<ControlTemplate TargetType="ToolTip">
<Border BorderBrush="Blue" BorderThickness="1" Background="White" CornerRadius="5">
<StackPanel Orientation="Vertical">
<DockPanel>
<TextBlock Text="{x:Static prop:strings.Laenge}" Margin="10" DockPanel.Dock="Left"/>
<TextBlock Text="{Binding LaengeD}" Margin="10" DockPanel.Dock="Right" />
</DockPanel>
<DockPanel >
<TextBlock Text="{x:Static prop:strings.Breite}" Margin="10" DockPanel.Dock="Left"/>
<TextBlock Text="{Binding BreiteD}" Margin="10" DockPanel.Dock="Right"/>
</DockPanel>
<DockPanel>
<TextBlock Text="{x:Static prop:strings.Hoehe}" Margin="10" DockPanel.Dock="Left"/>
<TextBlock Text="{Binding HoeheD}" Margin="10" DockPanel.Dock="Right"/>
</DockPanel>
<DockPanel>
<TextBlock Text="{x:Static prop:strings.Gewicht}" Margin="10" DockPanel.Dock="Left"/>
<TextBlock Text="{Binding Gewicht}" Margin="10" DockPanel.Dock="Right"/>
</DockPanel>
</StackPanel>
</Border>
</ControlTemplate>
</ToolTip.Template>
</ToolTip>
</Button.ToolTip>
</Button>

When your Tooltip is hidden, its PlacementTarget property is set to null and it is not linked to the logic tree of your button.
In this case your {Binding LaengeD} can't retrieve the correct value.
On the other side if you hover the button the PlacementTarget property is correctly set and your Binding can work.
So you can use this solution: add a DataContext binding to your tooltip
<Button Content="Click me" Margin="2" HorizontalAlignment="Center" Click="Button_Click" >
<Button.ToolTip>
<ToolTip DataContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={x:Static RelativeSource.Self}}">
<ToolTip.Template>
<ControlTemplate TargetType="ToolTip">
<Border BorderBrush="Blue" BorderThickness="1" Background="White" CornerRadius="5">
<StackPanel Orientation="Vertical">
<DockPanel>
<TextBlock Text="Laenge" Margin="10" DockPanel.Dock="Left"/>
<TextBlock Text="{Binding LaengeD}" Margin="10" DockPanel.Dock="Right" />
</DockPanel>
</StackPanel>
</Border>
</ControlTemplate>
</ToolTip.Template>
</ToolTip>
</Button.ToolTip>
</Button>
Then change your click event handler in this way:
private void Button_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
ToolTip tt = btn.ToolTip as ToolTip;
if (tt.PlacementTarget == null)
{
tt.PlacementTarget = btn;
}
tt.IsOpen = true;
}

Related

How do you add a flyout message to a WPF button using XAML

Below is my xaml for a button I would like to have a message fly out from:
<Button x:Name="ClearButton" HorizontalAlignment="Left"
Width="90" Margin="0,0,0,0"
Click="ClearButton_Click">
<StackPanel Orientation="Horizontal" Margin="-15,0,0,5" >
<Image Source="{StaticResource EraseButtonImageKey}"
Margin="5,0,0,0" Height="20" Width="20" />
<TextBlock VerticalAlignment="Center"
Padding="0,0,0,0" Margin="2,0,0,0">Clear</TextBlock>
</StackPanel>
</Button>
I would like to have a small single line of text fly out when a mouse pointer moves over a button in WPF. For example, if you are using the Chrome browser a small line of text fly's out when you move your cursor over the back arrow at the top which says "click to go back". How can I have a message like that pop out when I move a mouse pointer over a WPF button? The message I want displayed for my button would be "Removes all text from the results window."
Thanks in advance.
---- UPDATE FEB 9, 2019 ------
Thanks to the comment from the.doc I updated my code to the following which now gives me the result I was looking for:
<Button x:Name="ClearButton" HorizontalAlignment="Left"
Width="90" Margin="0,0,0,0"
Click="ClearButton_Click">
<StackPanel Orientation="Horizontal" Margin="-15,0,0,5" >
<Image Source="{StaticResource EraseButtonImageKey}"
Margin="5,0,0,0" Height="20" Width="20" />
<TextBlock VerticalAlignment="Center"
Padding="0,0,0,0" Margin="2,0,0,0">Clear</TextBlock>
</StackPanel>
<Button.ToolTip>
<ToolTip>
<StackPanel>
<TextBlock FontWeight="Bold">Removes all text from the result window</TextBlock>
</StackPanel>
</ToolTip>
</Button.ToolTip>
</Button>
Below is the solution to the problem I had by using the Button.ToolTip feature which The.Doc suggested:
<Button x:Name="ClearButton" HorizontalAlignment="Left"
Width="90" Margin="0,0,0,0"
Click="ClearButton_Click">
<StackPanel Orientation="Horizontal" Margin="-15,0,0,5" >
<Image Source="{StaticResource EraseButtonImageKey}"
Margin="5,0,0,0" Height="20" Width="20" />
<TextBlock VerticalAlignment="Center"
Padding="0,0,0,0" Margin="2,0,0,0">Clear</TextBlock>
</StackPanel>
<Button.ToolTip>
<ToolTip>
<StackPanel>
<TextBlock FontWeight="Bold">Removes all text from the result window</TextBlock>
</StackPanel>
</ToolTip>
</Button.ToolTip>
</Button>

TextBox does not exist in the current context in DataGrgid DataRowTemplate

I have a datagrid which on click will show a textbox for user input. I am able to display the details on the textbox. Now I have a Update button inside the datatemplate. Once i click on the update button I want the user input taken and do processing.
This is my xaml code:
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Border BorderThickness="0" Background="BlanchedAlmond" Padding="10">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="First Name: " VerticalAlignment="Center" />
<TextBox x:Name="txtFirstName" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserFirstName}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="Last Name: " VerticalAlignment="Center" />
<TextBox x:Name="txtLastName" FontSize="16" Foreground="MidnightBlue" Text="{Binding UserLastName}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel>
<Button x:Name="btnUpdate" Content="Update" VerticalAlignment="Center" HorizontalAlignment="Right" Click="btnUpdate_Click"/>
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
This is my .cs code:
void btnUpdate_Click(object sender, RoutedEventArgs e)
{
string firstName;
firstName = txtFirstName.Text;
}
The txtFirstName.Text is showing Does Not Exist In The Current Context
Because it's inside the datatemplate you may have to do something like https://code.msdn.microsoft.com/windowsapps/How-to-access-a-control-6039571a
Or use the binding that you already have, just make the mode TwoWay.
{Binding UserFirstName, Mode=TwoWay}

How to align the Pop up window when the Mainwindow minimizes in wpf

While my popup window is open, On Minimizing the mainwindow, The Popup window does not resizes and appears outside of the MainWindow.(See the image below)
Is there any way - where we can resize the popup window and align it within the MainWindow during minimize ? Here's my code:
MainWindow.xaml
<Button Height="54" Width="50" Margin="100,0,0,0" x:Name="btnNotification" FontFamily="Segoe UI Symbol" FontSize="20" Content="🔔" Command="{Binding LoadNotification}" Click="btnNotification_Click"/>
<Popup Name="NotificationPopup" IsOpen="False" Closed="PopupClosed" StaysOpen="False" PlacementTarget="{Binding ElementName=btnNotification}" Placement="Bottom" VerticalOffset="20">
<Grid x:Name="PopUpGrid" Height="560" Width="360" Background="White">
<StackPanel Orientation="Vertical" HorizontalAlignment="Right">
<Button BorderBrush="Transparent" BorderThickness="0" Background="White" >
<StackPanel Width="{Binding ActualWidth, ElementName=PopUpGrid}" Orientation="Vertical">
<WrapPanel>
<Rectangle Width="20"/>
<TextBlock Text="Notifications" Width="300" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="24" FontWeight="Light" />
<Button Click="btnNotification_Click" >
<StackPanel>
<TextBlock Text="✕" Foreground="Black" FontWeight="ExtraLight"/>
</StackPanel>
</Button>
</WrapPanel>
<Grid>
<!--Datagrid-->
</Grid>
</StackPanel>
</Button>
</StackPanel>
</Grid>
</Popup>
MainWindow.xaml.cs
public void PopupClosed(object sender, EventArgs e)
{
NotificationPopup.IsOpen = false;
}

UWP[Xaml] How to access elements inside Button

How to change txtPIN.Text value in C# code behind after UserControl was initialized.
Here is XAML
<Button x:Name="btn_pin" Content="Change PIN" Click="button_Click" Foreground="White">
<Button.Template>
<ControlTemplate TargetType="Button">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<Image Source="/Assets/images/settings/lock.png" Stretch="UniformToFill" Width="16" Height="16"/>
<TextBlock x:Name="txtPin" Text="Change PIN" Foreground="White" />
</StackPanel>
</ControlTemplate>
</Button.Template>
</Button>
and C#
public MyUserControl()
{
this.InitializeComponent();
this.btn_pin.??????????
}
You're not doing it the right way, just fix your xaml (I changed the Text binding of your TextBlock):
<Button x:Name="btn_pin" Content="Change PIN" Click="button_Click" Foreground="White">
<Button.Template>
<ControlTemplate TargetType="Button">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<Image Source="/Assets/images/settings/lock.png" Stretch="UniformToFill" Width="16" Height="16"/>
<TextBlock x:Name="txtPin" Text="{TemplateBinding Content}" Foreground="White" />
</StackPanel>
</ControlTemplate>
</Button.Template>
</Button>
and every time you want to change the text, change the Content of the button like this:
public MainPage()
{
this.InitializeComponent();
btn_pin.Content = "New label";
}

Why isn't my WPF Popup Showing Where it Should

I am trying to follow this guide : http://www.jarloo.com/excel-like-autofilter-in-wpf/ to add a small popup when a button in a datagrid column header is pressed. I have added a filter button and icon to the column header and set the popup's placement target as this button but the popup always displays at the bottom left of the whole window.
Any idea's why?
DataGrid Column
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="Images\bios.png" Width="16" Height="16"/>
<TextBlock Text="Model" TextWrapping="Wrap" Padding="3"/>
<Button Name="btnModelFilter" Margin="3,0,0,0" Click="btnModelFilter_Click">
<Button.Template>
<ControlTemplate>
<Image Source="Images\filter.png" Width="10" Height="10"/>
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
</DataGridTemplateColumn>
Popup
<Popup Name="popModel" Placement="Bottom" PlacementTarget="{Binding ElementName=btnModelFilter}" StaysOpen="False" Width="200">
<Border Background="White" BorderBrush="Gray" BorderThickness="1,1,1,1">
<StackPanel Margin="5,5,5,15">
<StackPanel Orientation="Horizontal" Margin="0,0,0,15">
<Button Margin="0,0,0,0" Name="btnSelectAll" Click="btnSelectAll_Click">
<Button.Template>
<ControlTemplate>
<TextBlock Text="Select All" Foreground="Blue" Cursor="Hand" />
</ControlTemplate>
</Button.Template>
</Button>
<Button Margin="10,0,0,0" Name="btnUnselectAll" Click="btnUnselectAll_Click">
<Button.Template>
<ControlTemplate>
<TextBlock Text="Select None" Foreground="Blue" Cursor="Hand" />
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
<ListBox x:Name="lstModels" BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Item}" Checked="ApplyFilters" Unchecked="ApplyFilters" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Border>
</Popup>
since the Name attribute of your button is defined within a DataTemplate, the scope of the name does not go beyond that DataTemplate, hence the button is not found and PopUp is displayed at 0,0.
This scope rule is logical because imagine if you re-use the DataTemplate several times, then having same button name would raise a compiler error.
You might define your PopUp as a style with a key, and include it in your Header DataTemplate directly.
Assuming that your popup is in the same stack panel of your btnModelFilter, I think your StackPanel (parent of the btnModelFilter) should be the placement target of the popup and not the btnModelFilter.

Categories

Resources