How to define stroke around background rectangle of textblock in WPF? - c#

I would like to have some text to be inside a rectangle with stroke around this rectangle (just like property "Stroke" of the object "Rectangle" itself). But I didn't manage to find a property of the object "Textblock" which defines such a stroke.

You can place the TextBlock inside a Border and set the properties of the Border to draw the rectangle around your text.

Every TextBlock element contains one or more child Inline elements. There is a type of Inline (InlineUIContainer) that supports hosting a UIElement: basically, this means you can host arbitrary UI elements within a TextBlock. Flipping #GraemeF's answer on its head, you can host a Border element inside the TextBlock, like so:
<Window x:Class="StackOverflowWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBlock FontSize="24" Padding="20">
<Run>Hello</Run>
<InlineUIContainer>
<Border BorderBrush="Black" BorderThickness="1" Padding="4" Margin="0,0,0,-11">
<TextBlock Text="Boxed" />
</Border>
</InlineUIContainer>
<Run>World</Run>
</TextBlock>
</Window>
This will look something like this:
You will have to experiment with the Margin on the Border element in order to get the text baselines to match up, but other than that the technique seems to work well.

Related

Canvas improperly overlaying a TextBlock component inside a DockPanel

In the image here, each block with a number in it represents a laser. These blocks are laid out on a canvas inside a DockPanel. Also inside the DockPanel docked to the top is the red TextBlock that you can see is hiding behind the laser map canvas. Why is this happening? The TextBlock is docked to the top of the DockPanel and canvas has no dock setting, therefore it should fill the rest of space. Also of note: I had to put the DockPanel inside a ViewBox in order for the whole center screen space to scale properly on window resizes. Then I had to put that ViewBox inside a ScrollViewer to allow scroll bars to appear when needed.
Here is the XAML Code for the center screen (Note: Child of the Window is a DockPanel. Menu is docked to the top, left-hand button panel is docked to the left, right-hand button panel is docked to the right, the status bar is docked to the bottom and everything you see in the center screen is defined by the following XAML code)
<ScrollViewer
Name="centerScreenScrollViewer"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="{Binding IsScrollbarsVisible, Converter={StaticResource BoolToScrollbarVisConverter}, FallbackValue=Hidden}">
<Viewbox>
<DockPanel
LastChildFill="True">
<TextBlock
DockPanel.Dock="Top"
Name="tbkFullVisual"
Style="{StaticResource tbkStyleBlue}"
Foreground="Red"
IsEnabled="{Binding FullVisual}"
HorizontalAlignment="Center"
VerticalAlignment="Top"
FontSize="24">
*** This Print Requires Full Visual Inspection! ***
</TextBlock>
<Canvas x:Name="mapCanvas">
<ContentPresenter Content="{Binding MapCanvas}"/>
</Canvas>
</DockPanel>
</Viewbox>
</ScrollViewer>
Any help in solving this issue will be greatly appreciated.
Regards,
Kyle
This has to do with the way that a ViewBox works, in particular with the Canvas element. The ViewBox is used to resize child elements, as I'm sure you're aware. There are 2 issues with the Canvas element:
The default Height and Width are 0, which means that the TextBlock will get all the space.
The Canvas element lets you draw outside of its own boundaries, so even if your canvas is tiny or not even visible, you would be allowed to render your grid of numbers.
The quickest solution is to set VerticalAlignment on the ViewBox:
<Viewbox VerticalAlignment="Top">
...
</Viewbox>
You could set a Height on the Canvas, but I think this is less ideal because you don't want to change this dynamically with window resize.

C# XAML ScrollViewer to work without MaxHeight

I have a grid that further down have a StackPanel. I have defined the row's height for the last to be "*", and in this very last row, is where the StackPanel and all the control would inhabit.
So I have the bellow code in XAML for my StackPanel
<StackPanel Grid.Row="1" MaxHeight="333">
<StackPanel MaxHeight="333">
<ScrollViewer MaxHeight="333">
<TextBlock x:Name="lblRouteDetail" FontSize="35" TextWrapping="Wrap"/>
</ScrollViewer>
</StackPanel>
</StackPanel>
Well, it worked, only that I have to constraint that the MaxHeight is 333, without that, it won't work; the ScrollViewer won't work, the content in the TextBlock wouldn't be scrollable.
Could you state where is my problem, and how to fix this things up?
A StackPanel, unless set to a specific height (or width if its orientation is set to Horizontal), does not constrain the height of its children, but is sized according to them. If you want to scroll your controls, you could either keep the MaxHeight property or use a different panel for holding them, such as a Grid or a DockPanel.

How to change control alignment depending on available space?

Imagine this. I've got a Border which contains some custom wpf control, lets call it MyControl. This Border stretches itself when window is resized (to fill available space). MyControl size is fixed. Now, I want my control to have HorizontalAlignment="Center" when it fits the available space, and HorizontalAlignment="Left" when it doesn't. I'm having trouble figuring out how to implement such behaviour though.
I guess, i can subscribe to Border's SizeChanged event and change alignment in code-behind depending on ActualWidths of Border and MyControl, but isn't there an easier way? Can this be achieved by databinding or by attached behaviour?
It will automatically behave like that if you set the control's Width and Height to fixed values and HorizontalAlignment and VerticalAlignment to Stretch instead of Center:
<Border BorderBrush="Red" BorderThickness="5">
<my:MyControl Width="200" Height="150"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Border>

scrollviewer with the textbox

I have a textbox which is contained in a scrollviewer as below:
<ScrollViewer x:Name="myScrollViewer" Height="200" Width="500" HorizontalAlignment="Left">
<TextBox x:Name="myTextBox" Width="500" TextWrapping="Wrap"/>
</ScrollViewer>
When I input a large number of data in the textbox, the scrollviewer will not scroll down automatically, so this lead I couldn't see what I'm inputing now in the textbox, I have to scroll down manully and see the content which I am inputting. I have two questions:
How to let the scrollbar automatically scroll down follow the line which I am writing now.
TextBox has a border, but if I scroll down, the top border will disappear, it looks like the text box is scroll up, how to make the textbox not changes, the 4 borders always appear and only the content wrapped?
Do you need to use a ScrollViewer, or can you use the TextBox's own scrolling behaviour?
This behaves as you would want in normal Silverlight apps (can't test it on a windows 8 app right atm)
E.G.
<TextBox
Height="200"
Width="500"
TextWrapping="Wrap"
AcceptsReturn="True"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto"/>
(Note that you don't seem to be able to set the HorizontalScrollBarVisibility and VerticalScrollBarVisibility properties from a Style)

Aligning content in a WPF Viewbox

I have a Viewbox with Stretch=Uniform in order to not distort the content.
However, when the frame window is wider or taller than the content, the Viewbox content is always centered.
I cannot seem to find any content alignment options on the Viewbox.
Is there a way to do this?
Try VerticalAlignment="Top" and HorizontalAlignment="Left" on your viewbox. It will cause it to be anchored to the top and left side.
<Grid>
<Viewbox VerticalAlignment="Top" HorizontalAlignment="Left">
...
</Viewbox>
</Grid>
If you want it to completely fill (but keep it uniform) you can use Stretch="UniformToFill"
According to MSDN the Viewbox is used to stretch the child elements. Since the child elements would be stretched, you would have to set the content alignment of the children.
You may want to look at this for more information on the Viewbox: How do I keep aspect ratio on scalable, scrollable content in WPF?

Categories

Resources