How to vertically align a TextBox based on its content - wpf

I have a text block I want to vertically align so it appears in the center of a circle. It's a single character, such as 'a', 'y', '?', 'R' or any other valid character. It could have a descender, ascender, be a capital, non alphabetical etc.
With the following code, it appears to align the text block according to the height of a capital letter. So a lower case letter appears too low, and letter with a descender even more so.
<Grid Width="32" Background="Green" Height="32">
<Ellipse Width="32" Height="32" Stroke="Red" Fill="White"/>
<TextBlock Text="{Binding Character}" Foreground="Blue" HorizontalAlignment="Center" FontWeight="Bold" VerticalAlignment="Center" FontFamily="Arial" FontSize="28"/>
</Grid>
Is there a way to get to align vertically based on the text content of the TextBlock, instead of the reserved area of the text that might be in it?
If it is not possible, what other controls / methods are available in WPF to achieve this?

Landerah in you code only if i set magin for textblock, than i can set text where i want. You can also set margin dynamically i.e If character is lower case set magin bit above like test.Margin = new Thickness(0, -2, 0, 0);
<Grid Width="32" Background="Green">
<Ellipse Width="32" Height="32" Stroke="Red" Fill="White"/>
<TextBlock Margin="0,-2,0,0" Text="r" Foreground="Blue" HorizontalAlignment="Center" FontWeight="Bold" VerticalAlignment="Center" FontFamily="Arial" FontSize="28"/>
</Grid>

A more complete sample that works for me -
<ControlTemplate TargetType="{x:Type local:LevelControl}">
<Viewbox x:Name="Frame">
<Grid Margin="2" Background="Transparent" VerticalAlignment="Center" HorizontalAlignment="Center" Width="26" Height="26">
<Ellipse x:Name="outerEllipse" Fill="{Binding Fill, ElementName=innerEllipse}" Stretch="UniformToFill" Grid.Row="0" Opacity="0.5" />
<Ellipse x:Name="innerEllipse" Fill="Gray" Stretch="UniformToFill" Margin="4" Grid.Row="0" />
<TextBlock x:Name="Label" FontWeight="Bold" FontSize="18" Foreground="White" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="7.948,0,7.698,2.125" />
</Grid>
</Viewbox>
</ControlTemplate>
or try a label <Label VerticalAlignment="Center" VerticalContentAlignment="Center" ></Label>

Related

WPF XAML: place Image near TextBlock but align text to center of row

I have a similar structure in a WPF app:
<Grid Background="White">
<StackPanel>
<TextBlock Text="1234567" FontSize="18" FontWeight="Bold" Height="25" TextAlignment="Center"/>
<Line X1="0" Y1="0" X2="160" Y2="0" Stroke="Gray" StrokeThickness="2"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Width="25" Height="25" Grid.Column="0" Source="img.png" />
<TextBlock Grid.Column="1" Text="3456789" FontSize="18" FontWeight="Bold" Height="25" TextAlignment="Center"/>
</Grid>
</StackPanel>
This results in the following layout:
Is there any way to place the bottom text in the center of the row, so it's alignment would match with the text above?
Or is there a solution to place the image on top of the bottom row on the left side without column definitions?
Thanks
Use a single-cell grid with different alignments. You will run the risk of long text being under the image, and you will have to set a Width value on the StackPanel. See the HorizontalAlignment flag below:
<Grid>
<TextBlock Text="3456789" FontSize="18" FontWeight="Bold" Height="25" HorizontalAlignment="Center"/>
<Image Width="25" Height="25" Source="img.png" HorizontalAlignment="Left" />
</Grid>

Textbox focus does not work

I am using VS2015 and currently I am under pressure of this issue and I don't know why it's not working on VS2015.
I do have a "Splash Screen" which is a welcome page and after that will be another page to show some other forms. I do have 5 borders represent as a container, each border will show after hit next and all of the borders are place only in the same View which is MainWindow.xaml.
Every field just like Name textbox field do have a Validation.ErrorTemplateand I am not sure if that will affect the textbox focus.
I used FocusManager.FocusedElement and text1.focus() but still not working and other solution coming from other people having similar issues but still not working in my end.
I am guessing something in logical focus but when I force to focus the textbox still not working.
Simple example of XAML.
<Border x:Name="Panel1" Opacity="0" IsHitTestVisible="False"
RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform Y="515" />
</TransformGroup>
</Border.RenderTransform>
<Grid Background="{DynamicResource ActiveBrush}">
<ScrollViewer Margin="0,10,0,76.33" Height="450" Width="630" VerticalAlignment="Top"
VerticalScrollBarVisibility="Auto"
Template="{DynamicResource ContentPanelScrollviewerStyle}">
<StackPanel Orientation="Vertical" Width="630">
<Label Content="Name" HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="{DynamicResource FieldGroupHeadingTextSize}"
Foreground="{DynamicResource TextBrush}" />
<Grid Height="170">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Column="0" IsVisibleChanged="Grid_IsVisibleChanged">
<StackPanel>
<Label Content="Name"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="{DynamicResource FieldLabelTextSize}"
Foreground="{DynamicResource TextBrush}" />
<TextBox Name="text1" Validation.ErrorTemplate="{StaticResource validationTemplate}"
HorizontalAlignment="Left" TextWrapping="Wrap"
Text="{Binding Name, NotifyOnValidationError=True}"
VerticalAlignment="Top" Width="298.8" Height="24"
FontSize="{DynamicResource FieldInputTextSize}"
Foreground="{DynamicResource TextBrush}">
<i:Interaction.Behaviors>
<behaviors:ReadOnlyWhileValidatingBehavior />
</i:Interaction.Behaviors>
</TextBox>
</StackPanel>
</Grid>
</Grid>
</StackPanel>
</ScrollViewer>
</Grid>
</Border>

TextBox with image icon in WPF

I want to create TextBox with image in it. This is what I have tried:
<DockPanel Grid.Row="1" Grid.Column="1" Margin="5" >
<Image DockPanel.Dock="Left" Source="D:\my_backup\WPF\SALIENT\SALIENT\Images\d2.PNG" Width="20" Height="20"></Image>
<TextBox Text="test" FontSize="16" HorizontalAlignment="Stretch" Background="Transparent"
</TextBox>
</DockPanel>
this gives me output like this:
but i want the image inside TextBox like this
anyone can help?
You could use this sort of implementation.
you should probably make a user control out of it.
<Border BorderBrush="Black"
BorderThickness="2"
VerticalAlignment="Center"
CornerRadius="5">
<StackPanel Margin="5"
Orientation="Horizontal">
<Image Source="C:\SourceOfTheImage\Path\Image.png"
Height="18"/>
<TextBlock Text="Hello, I am a text block!"
Margin="3 0 0 0"/>
</StackPanel>
</Border>
It looks like this for me
You can set the background property on Textbox, like this (mine is align on right) :
<TextBox x:Name="txtSearch"
Text="Search Item...">
<TextBox.Background>
<ImageBrush ImageSource="Images/Search.png" Stretch="Uniform" AlignmentX="Right">
<ImageBrush.Transform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform X="-3"/>
</TransformGroup>
</ImageBrush.Transform>
</ImageBrush>
</TextBox.Background>
</TextBox>
Set AlignmentX to left if you want to see the image on the left side. Set the TranslateTransform.X to a positive value to add a margin.
Try this:
<Border Padding="5" BorderThickness="2,2,2,2" BorderBrush="Gray" CornerRadius="2,2,2,2">
<DockPanel Grid.Row="1" Grid.Column="1" Margin="5" >
<Image DockPanel.Dock="Left" Source="D:\my_backup\WPF\SALIENT\SALIENT\Images\d2.PNG" Width="20" Height="20"></Image>
<TextBox Text="test" FontSize="16" HorizontalAlignment="Stretch" Background="Transparent" BorderBrush="Transparent" ></TextBox>
</DockPanel>
</Border>
That would be the simplest one-off way of doing it.
You could dump it in a UserControl for reuse.
A second way of achieving this would be to open up the TextBox template and put this icon of yours inside the makeup of the TextBox, which would allow you to avoid needing the DockPanel and Border here, as well as allowing you to make the Template a resource you can easily attach to any Textbox in the future.

Imagebrush is stretching one instance of an image but not another

One of the stranger occurrences I've come across, I have a set of repeatbuttons that use a certain image as a background. Despite the buttons being identical, one is displayed differently. Fully reproducible sample below, along with a number of variations each with different results.
Link to icons:
https://github.com/driftyco/ionicons/blob/master/png/512/plus.png
https://github.com/driftyco/ionicons/blob/master/png/512/minus.png
<Grid Margin="0,0,0,0" >
<StackPanel Orientation="Horizontal" Height="32">
<StackPanel.Resources>
<ImageBrush x:Key="plusImage" ImageSource="/Resources/plus.png" />
<ImageBrush x:Key="minusImage" ImageSource="/Resources/minus.png" />
</StackPanel.Resources>
<RepeatButton Width="20"
Height="20"
Background="{Binding Source={StaticResource minusImage}}"/>
<TextBlock Margin="5,0,5,0"
VerticalAlignment="Top"
FontWeight="Bold"
Text="X" />
<RepeatButton Width="20"
Height="20"
Background="{Binding Source={StaticResource plusImage}}"/>
<Separator Margin="5,0,5,0" Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" />
<RepeatButton Width="20"
Height="20"
Background="{Binding Source={StaticResource minusImage}}"/>
<TextBlock Margin="5,0,5,0"
VerticalAlignment="Top"
FontWeight="Bold"
Text="Y" />
<RepeatButton Width="20"
Height="20"
Background="{Binding Source={StaticResource plusImage}}"/>
<Separator Margin="5,0,5,0" Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" />
<RepeatButton Width="20"
Height="20"
Background="{Binding Source={StaticResource minusImage}}"/>
<TextBlock Margin="5,0,5,0"
VerticalAlignment="Top"
FontWeight="Bold"
Text="Z" />
<RepeatButton Width="20"
Height="20"
Background="{Binding Source={StaticResource plusImage}}"/>
</StackPanel>
</Grid>
I'm creating a control to control the x, y, z positions of a point. As you can see in the image above, only one of the plus icons appears to be stretched.
Variations:
If I remove Z and the icons associated with it, the last plus icon for Y is NOT stretched
Removing the fontweight from Z makes the plus icon appear normal (not stretched)
What would cause an imagebrush to stretch an image like this?
You could set the UseLayoutRounding property on the RepeatButtons:
<RepeatButton Width="20" Height="20" UseLayoutRounding="True"
Background="{Binding Source={StaticResource plusImage}}"/>

How can I set opacity of a textbox to 1 when it is within a border with opacity 0.5?

I have the following xaml:
<Border x:Name="baseBorder" Grid.Row="0" Grid.RowSpan="200" Canvas.ZIndex="1" Opacity="0.5" Background="Gray">
<Border x:Name="interiorBorder" Background="White" Height="200" Width="450" Opacity="1">
<TextBlock x:Name="txtMessage" HorizontalAlignment="Center" Width="400" TextAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Center" FontSize="20" FontWeight="Bold" Foreground="Black" >
</Border>
</Border>
I want the interiorBorder to have opacity 1 while maintaining the base border's opacity 0.5.
The above xaml is not working, I'm getting 0.5 opacity in both objects.
Try making interiorBorder a sibling of baseBorder instead of a child, perhaps something like this.
<Border x:Name="baseBorder" Grid.Row="0" Grid.RowSpan="200" Canvas.ZIndex="1" Opacity="0.5" />
<Border x:Name="interiorBorder" Grid.Row="0" Grid.RowSpan="200" Canvas.ZIndex="1" Opacity="1">
<TextBlock x:Name="txtMessage" />
</Border>
I imagine you'll also want to set Margin on interiorBorder so you'll still be able to see baseBorder.

Resources