MouseOver on ToggleButton to popup a Text - wpf

I am coding to popup a Text when MouseOver on ToggleButton. I got it too, but the real problem is that popped Text is not remains constant i.e., it continuously shaking on the ToggleButton. One more thing is that popped Text is appeared on the ToggleButton itself but it should be beneath of it. How can i get rid of this one?
Here is my Code looks
<ToggleButton x:Name="btn" Width="20" Height="15">
<Image Source="../Images/flag_orange.ico"/>
</ToggleButton>
<Popup x:Name="popUp" IsOpen="{Binding IsChecked, ElementName=btn, Mode=TwoWay}"
StaysOpen="False" PlacementTarget="{Binding ElementName=btn}"
Placement="Bottom" PopupAnimation="Slide" HorizontalOffset="-5"
VerticalOffset="3">
<Border Background="DarkGray">
<TextBox Text="Its a place holder for user notes" x:Name="tbText"/>
</Border>
</Popup>
<TextBlock x:Name="tbTextBlock"
Visibility="{Binding Path=IsMouseOver,ElementName=btn,Mode=OneWay,
Converter={StaticResource BoolToVisibilityConverter}}"
Text="{Binding ElementName=tbText, Path=Text, Mode=TwoWay}" />

use IsHitTestVisible="False" on your TextBlock. The Mouseover is catched by the Textblock yet, so your mouse is not over the ToggleButton when the TextBlock appears.
To get the TextBlock beneath the ToggleButton use either a Margin="0,15,0,0" or a StackPanel to get those controls in order:
<StackPanel>
<ToggleButton x:Name="btn" Width="20" Height="15">
<Image Source="../Images/flag_orange.ico"/>
</ToggleButton>
<Popup x:Name="popUp" IsOpen="{Binding IsChecked, ElementName=btn, Mode=TwoWay}"
StaysOpen="False" PlacementTarget="{Binding ElementName=btn}"
Placement="Bottom" PopupAnimation="Slide" HorizontalOffset="-5"
VerticalOffset="3">
<Border Background="DarkGray">
<TextBox Text="Its a place holder for user notes" x:Name="tbText"/>
</Border>
</Popup>
<TextBlock x:Name="tbTextBlock"
IsHitTestVisible="False"
Visibility="{Binding Path=IsMouseOver,ElementName=btn,Mode=OneWay,
Converter={StaticResource BoolToVisibilityConverter}}"
Text="{Binding ElementName=tbText, Path=Text, Mode=TwoWay}" />
</StackPanel>

Related

Have popup show up below parent with horizontal alignment wpf

How would I be able to have a popup which has a horizontal alignment to center, but still keep the placement to be below the parent item like this:
What I Have:
Code:
<ToggleButton Name="button" Foreground="Black" VerticalAlignment="Center" HorizontalAlignment="Center">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<TextBlock>settings</TextBlock>
<!--<materialDesign:PackIcon Kind="PackageVariantClosed" Foreground="Black" Height="24" Width="24"/>-->
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<Popup Placement="Bottom" PlacementTarget="{Binding ElementName=button}" IsOpen="{Binding IsChecked, ElementName=button}" StaysOpen="False">
<Border Background="#222" Height="150" Width="250">
<TextBlock>I'm the popup</TextBlock>
</Border>
</Popup>
What I want:
You can use the HorizontalOffset property of the popup. If you know the width of the toggle button you can set a number in XAML:
<Popup Placement="Bottom" PlacementTarget="{Binding ElementName=button}"
HorizontalOffset="-100"
IsOpen="{Binding IsChecked, ElementName=button}" StaysOpen="False">
If you want a more generic approach, in the code behind you can calculate the exact offset that is needed:
popup.HorizontalOffset = -125 + button.ActualWidth / 2;

How to bind to property of sibling control?

In a listbox of items, one item can be designated as the primary item. In the template, I have a button bound to a parameterized command (the specific item in the collection is the parameter passed to the command in the datacontext) that is visible only if the item is not currently the primary item. If the item IS the primary item, I want to display a static image. Since I can't bind the image to the command to witch I am binding the button, I figured I could bind the Visibility property of the image to the "inverse" of the Visibility property of the button. (i.e. when the button is visible, the image is hidden and vice versa.) But I can't figure out how to do this. The button is a sibling of the image within a grid within the template. Here's my template...
<DataTemplate>
<StackPanel Orientation="Vertical">
<Grid>
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=FormattedNumber}" Style="{StaticResource FieldDataTextBlock}" FontWeight="Bold" />
<!-- How can I make this image aware of the following button's state? -->
<Image Grid.Column="2" Source="/Resources/Star.Pressed.png" Visibility="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path={}}" Width="20" Height="20" />
<Button Grid.Column="2" x:Name="btnMakePrimary" Style="{StaticResource StarButton}" Command="{Binding ElementName=lstPhoneNumbers, Path=DataContext.MakePrimaryPhoneNumberCommand}" CommandParameter="{Binding}" ToolTip="Set as display number." Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Converter={StaticResource BoolVisibility}}" />
<Button Grid.Column="4" Style="{StaticResource DetailsButton}" Command="{Binding ElementName=lstPhoneNumbers, Path=DataContext.ViewPhoneNumberCommand}" CommandParameter="{Binding}" />
<Button Grid.Column="6" Style="{StaticResource DeleteButton}" Command="{Binding ElementName=lstPhoneNumbers, Path=DataContext.DeletePhoneNumberCommand}" CommandParameter="{Binding}" />
</Grid>
<Grid >
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=PhoneTypeString}" Style="{StaticResource FieldDataTextBlock}" />
<TextBlock Grid.Column="2" Text="(notes)" Foreground="Blue" ToolTip="{Binding Path=PhoneNumberNote}" Visibility="{Binding Path=HasNote, Converter={StaticResource BoolVisibility}}" />
</Grid>
</StackPanel>
</DataTemplate>
Either that, or is there a way to bind the image to a method in the parent datacontext that takes a parameter?
Thanks.
J
Never mind... I was able to make it happen via the ElementName attribute of the binding and fixing an issue with the included image resource which was messing with my visuals:
<Button Grid.Column="2" Name="btnMakePrimary" Style="{StaticResource StarButton}" Command="{Binding ElementName=lstPhoneNumbers, Path=DataContext.MakePrimaryPhoneNumberCommand}" CommandParameter="{Binding}" ToolTip="Set as display number." Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Converter={StaticResource BoolVisibility}}" />
<Image Grid.Column="2" Source="/Resources/Star.Pressed.png" Visibility="{Binding ElementName=btnMakePrimary, Path=IsEnabled, Converter={StaticResource BoolVisibilityReverse}}" Width="20" Height="20" />

Adding image to radiobutton that can act as Toggle button using wpf

I want to use 2 radiobuttons like a toggle button using WPF. I tried something like this:
<RadioButton Name="RightAnswer" Width="20">
<RadioButton.Template>
<ControlTemplate>
<ToggleButton IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
<Image Width="20"
Height="20"
VerticalAlignment="Center"
Source="{Binding Content,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay}"
ToolTip="Right Answer" />
</ToggleButton>
</ControlTemplate>
</RadioButton.Template>
</RadioButton>
<RadioButton Name="WrongAnswer" Width="20">
<RadioButton.Template>
<ControlTemplate>
<ToggleButton IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
<Image Width="20"
Height="20"
VerticalAlignment="Center"
Source="{Binding Content,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay}"
ToolTip="Wrong Answer" />
</ToggleButton>
</ControlTemplate>
</RadioButton.Template>
</RadioButton>
I could make this work but it shows blank buttons. I want to have buttons with Image in each of them and on checked i should bind it with ViewModel code.
Update: I added Images in each of them which now works well. I hoping to connect the press events to VM property.

Modifying TabControl's header

So I'm adding my views directly to the TabControl's Items collection at runtime (instead of creating TabItems around them and addings those TabItems to TabControl). The views expose a property (wrapper around a ViewModel property of the same name) named HasChanges that I want to bind to TabItem's Header to show a Asterisk (*) sign to identify tabs with unsaved changes, just like VS does. I have already tried using DataTemplates but am having trouble accessing the view object in the DataTemplate. What's the correct way of doing this? Here's one of my several attempts:
<TabControl.ItemTemplate>
<DataTemplate DataType="UserControl">
<StackPanel Orientation="Horizontal" Margin="0" Height="22">
<TextBlock VerticalAlignment="Center" Text="{Binding HeaderText, RelativeSource={RelativeSource AncestorType=UserControl}}" />
<TextBlock Text="*" Visibility="{Binding HasChanges, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource B2VConverter}}" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
Note that I'm trying two different binding methods for the two TextBlocks, none of which is working. My views inherit from UserControl and expose properties HasChanges and HeaderText.
OK. I solved it myself. For anyone else trying to implement a VS-like Close button and unsaved changes asterisk, here's the template:
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="HeaderTemplate" >
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0" Height="22">
<TextBlock VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource AncestorType=TabItem}, Path=Content.HeaderText}" />
<TextBlock Text=" *" ToolTip="Has unsaved changes" Visibility="{Binding Content.DataContext.HasChanges, RelativeSource={RelativeSource AncestorType=TabItem}, Converter={StaticResource B2VConverter}}" />
<Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Width="18" Height="18"
Margin="6,0,0,0" Padding="0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Center"
Command="{Binding DataContext.TabClosingCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"
VerticalAlignment="Center" Focusable="False">
<Grid Margin="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Line StrokeThickness="3" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Stroke="Gray" X1="1" Y1="1" X2="9" Y2="9" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Line StrokeThickness="3" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Stroke="Gray" X1="1" Y1="9" X2="9" Y2="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Button>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.ItemContainerStyle>
Results in an elegant drawing-based button with a flat-look. Your View must implement Boolean HasChanges and HeaderText properties, plus you need to define a BooleanToVisibilityConverter in your resources section, named B2VConverter.

How to apply Style of Parent control to Child controls in content template in Silverlight

Here My TextBox text is being bind to child text box in contentemplate but how to apply along with default style and validation errors to the child textbox in content template.
<TextBox x:Name="tbIdNumber" Width="110" Height="20" Text="{Binding IdNumber, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" >
<TextBox.Template>
<ControlTemplate TargetType="TextBox" >
<StackPanel Orientation="Horizontal" >
<Image Height="10" Width="20" Source="Images/bullet_darkblue.PNG" />
<TextBox Width="90" Tag="{Binding RelativeSource={RelativeSource TemplatedParent}}" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent},Path=DataContext, Mode=TwoWay}"
Text="{Binding Path=Text ,RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" >
</TextBox>
</StackPanel>
</ControlTemplate>
</TextBox.Template>
</TextBox>
It is very unusual to define the control template for TextBox control with a TextBox. I suggest you not pursue the path above.
You should instead start off with the default ControlTemplate for a TextBox here (Warning: it is very complex). It contains all the necessary visual states for validation, focused, etc.
From what I observe, you want to add an image next to the textbox. You should be able to add an image element inside the Grid and then perhaps adjust the margin on the Border. Here's a snippet:
<Image Height="10" Width="20" Source="Images/bullet_darkblue.PNG" />
<Border Margin="20,10,0,0"
x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent">
<ScrollViewer x:Name="ContentElement" Padding="{TemplateBinding Padding}"
BorderThickness="0" IsTabStop="False"/>
</Border>

Resources