Set superscript and subscript in formatted text in wpf - wpf

How can I set some text as subscript/superscript in FormattedText in WPF?

You use Typography.Variants:
<TextBlock>
<Run>Normal Text</Run>
<Run Typography.Variants="Superscript">Superscript Text</Run>
<Run Typography.Variants="Subscript">Subscript Text</Run>
</TextBlock>

You can use something like <TextBlock>5x<Run BaselineAlignment="Superscript">4</Run> + 4</TextBlock>.
However, as far as I know, you will have to reduce the font-size yourself.

It's interesting to note that for some characters (m2, m3, etc) a superscript is not needed, but the unicode character can be used. For example:
<Run Text=" m³" />
This would show m3.

I used a layout transform, because Typography.Variants often doesn't work:
<TextBlock Text="MyAmazingProduct"/>
<TextBlock Text="TM">
<TextBlock.LayoutTransform>
<!-- Typography.Variants="Superscript" didn't work -->
<TransformGroup>
<ScaleTransform ScaleX=".75" ScaleY=".75"/>
<TranslateTransform Y="-5"/>
</TransformGroup>
</TextBlock.LayoutTransform>
</TextBlock>
<TextBlock Text="{Binding Path=Version, StringFormat={} v{0}}"/>
The advantage of using a LayoutTransform is that it is insensitive to the fontsize. If the fontsize is changed afterwards, this superscript works where explicit FontSize setting breaks.

I don't know if you need this to work with FormattedText specifically, or you mean derivations of Inline, but the following will work on Inlines, even if Typography.Variants="Superscript" fails to work.
TextRange selection = new TextRange(document.ContentStart, document.ContentEnd);
selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Superscript);
Hope it helps!

Typography.Variants works only for open type fonts. If you dont like your superscripts/subscripts going outside the height of actual text then you can use something like the following:
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="10" Margin="0,5,0,0">1</TextBlock>
<TextBlock FontSize="30">H</TextBlock>
<TextBlock FontSize="10" Margin="0,20,0,0">2</TextBlock>
</StackPanel>

This is the only thing that worked for me. It also gives you more control over the alignment and font size.
<TextBlock Grid.Row="17">
3 x 3<Run FontSize="6pt" BaselineAlignment="TextTop">2</Run>)
</TextBlock>

Setting for superscript works fine with the following code:
<TextBlock Text="(cm" />
<TextBlock ><Span BaselineAlignment="Top" FontSize="8">2</Span></TextBlock>
<TextBlock Text=")" />
Setting the Baseallignment for subscript in the Span tag did not work for me.
I tried the following code and it worked fine.
<TextBlock Text="H" />
<TextBlock Text="2" Margin="-2,0,-2,0" TextBlock.LineHeight="3" >
<TextBlock Text="O" />

Related

How can I center align text with hyperlinks in it?

How can I center align text with hyperlinks in it?
I need to have the some text below, and with the XAML I got it's currently not centered. In fact, Horizontal Alignment does not seem to have any effect. Hyperlinks are working fine, however.
This is inside a grid with 2 columns, and I need the ColumnSpan to be 2.
Thanks.
"By clicking Sign In, you agree to our [HYPERLINK: Privacy Policy] and [HYPERLINK: Terms of Use.]"
<TextBlock Grid.Row="3" Grid.ColumnSpan="2" TextWrapping="Wrap" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontSize="18px">
<Run Text="By clicking Sign In, you agree to our " />
<Hyperlink NavigateUri="https://www.my-company-website.com/privacy-policy/" RequestNavigate="Hyperlink_RequestNavigate">
Privacy Policy
</Hyperlink>
<Run Text=" and "/>
<Hyperlink NavigateUri="https://www.my-company-website.com/terms-and-conditions/" RequestNavigate="Hyperlink_RequestNavigate">
Terms of Use.
</Hyperlink>
</TextBlock>
I think you are looking for the TextAlignment property. Set this one to Center:
<TextBlock TextAlignment="Center" ...

Add image into a tooltip

I have some TextBlocks with tooltips and I'd like to add an image into the tooltips (that means, I'd like to have tooltips with text and images).
Does anybody knows how could I do that in a simple way?
Thanks a lot!
This is one way to approach it:
<TextBlock>
<TextBlock.ToolTip>
<StackPanel Orientation="Horizontal">
<Image Source="images/Item 2.gif" />
<TextBlock>My tooltip text</TextBlock>
</StackPanel>
</TextBlock.ToolTip>
Here is my text.
</TextBlock>
Instead of
<TextBlock ToolTip="Content"/>
You can do:
<TextBlock>
<TextBlock.ToolTip>
<!--insert everything you want here-->
<TextBlock Text="Content"/>
</TextBlock.ToolTip>
</TextBlock>

Inline object in TextBlock with TextTrimming = CharacterEllipsis or WordEllipsis

If you run this code and minimize/maximize width of the window
<TextBlock TextTrimming="WordEllipsis" >
<Run Text="I want that this rectangle will be placed "/>
<Rectangle Fill="Black" Width="20" Height="10" />
<Run Text=" here when I minimize width of the window"/>
</TextBlock>
you will see what Rectange will shift to the left side.
Is a bug in the WPF?
I guess this is not a bug.
Try to take TextTrimming="WordEllipsis" property off the text block (it affects the whole control)
and you will see that the rectangle wont move with you window size changes beacause you dont have any HorizentalAligment properties.
While it seems to be a bug, this might be a workaround:
<TextBlock TextTrimming="WordEllipsis" >
<Run Text="I want that this rectangle will be placed "/>
<Run Text="■" FontSize="40" BaselineAlignment="Center"/>
<Run Text=" here when I minimize width of the window"/>
</TextBlock>
See Unicode Characters in the Geometric Shapes Block.

WPF: Is there a sort of XAML tag that behaves like the HTML span element?

Coming from ASP.NET, this WPF stuff is just confusing. All I want to do is put a red asterisk by a label to indicate a required field. Playing around with stuff, I found that this actually does the trick:
<TextBlock Grid.Row="6" Height="28" HorizontalAlignment="Left" VerticalAlignment="Top">
<Label Foreground="Red" Content="*" /><Label Content="Heavy Weight" />
</TextBlock>
Being that I just came up with this, I am not convinced it's the academic route a seasoned WPF developer would take. Additionally, this markup puts a huge amount of white space in between the asterisk and the label. In HTML, a span element would just render right beside its next sibling element. FYI, I tried putting a label within a label, but VS2010 kept barking about "The property 'content' is set more than once".
Any ideas?
Something like this would be more appropriate:
<TextBlock Grid.Row="6" Height="28" HorizontalAlignment="Left" VerticalAlignment="Top">
<Span Foreground="Red">*</Span>Heavy Weight
</TextBlock>
Here is an overview of what can go into a TextBlock's content, more specifically here.
one more way is
<TextBlock Grid.Row="6" Height="28" HorizontalAlignment="Left" VerticalAlignment="Top">
<Run Foreground="Red" Text="*" />
<Run Text="Heavy Weight" />
</TextBlock>
btw
Damascus's solution adds more UI Elements.
with CodeNaked's solution, its difficult to databind the Text.
The explanation is that you actually put two elements one after the other. You need to put them into a container.
Just a sample code of a sentence with red asterisk I did recently:
<StackPanel Orientation="Horizontal" Margin="5" >
<TextBlock Text="Display name"/>
<TextBlock Text="*" Foreground="Red" FontWeight="Bold" />
<TextBlock Text=":"/>
</StackPanel>
There, everything is in a StackPanel, so property 'content' will actually be set once (if you don't specify a group panel such as this one, you'll have to add only one element)

Having hardcoded text with a binding in a TextBlock

In WPF, is there any way to have the Text property of a TextBlock to contain both hard coded text and a specific binding?
What I have in mind is something along the lines of the following (ofcourse, the below doesn't compile):
<TextBlock Text="Number of Fans: {Binding Artist.Fans.Count}"></TextBlock>
There is, if you are on .Net 3.5 SP1
<TextBlock Text="{Binding Path=Artist.Fans.Count,
StringFormat='Number of Fans: {0}'}" />
In using the above approach:
<TextBlock Text="{Binding Path="Artist.Fans.Count,
StringFormat='Number of Fans: {0}'}" />
I found it somewhat restrictive in that I couldn't find a way to bold face inside the StringFormat nor could I use an apostrophe in the StringFormat.
Instead I went with this approach, which worked better for me:
<TextBlock TextWrapping="Wrap">
<Run>The value</Run>
<Run Text="{Binding Path=MyProperty1, Mode=OneWay}" FontWeight="Bold" />
<Run>was invalid. Please enter it with the format... </Run>
<LineBreak/><LineBreak/>
<Run>Here is another value in the program</Run>
<Run Text="{Binding Path=MyProperty2, Mode=OneWay}" FontWeight="Bold" />
</TextBlock>
Use Binding.StringFormat:
<TextBlock Text="{Binding Artist.Fans.Count, StringFormat='Number of Fans: {0}'}"/>
Here the binding value(clouds.all) is added with "%". You can add any value you want after "\{0\}".
<TextBlock Text="{Binding Path=clouds.all, StringFormat=\{0\}%}"/>
With XAML using Template 10 and MVVM:
Just to be clear:
By definition, binding binds values to properties of controls.
Under the MVVM paradigm as implemented in the 'Template 10' framework, the values are initialized in the ViewModel associated to the relevant XAML page.
Here is how to have hardcoded text together with a binding in a Text property:
<Page
...
xmlns:vm="using:doubleirish.ViewModels"
xmlns:sys="using:System"
xmlns:controls="using:Template10.Controls"
...
<Page.DataContext>
<vm:StocksViewModel x:Name="ViewModel" />
</Page.DataContext>
...
<controls:PageHeader ... Text="{x:Bind sys:String.Format('Ticker : {0}', ViewModel.Ticker)}">
...
</Page>
The solution that worked for me:
<Label Content="{Binding Artist.Fans.Count}" ContentStringFormat="Number of {0}"/>

Resources