TextBlock filling vertical space - wpf

I want to create a TextBlock (or some other element with text in it for display only) that is vertical (-90 transform angle), but I want that element to fill up the vertical space it is contained in, but have a defined horizontal amount (I'm using vertical and horizontal terms instead of height and width since it's swapped when I have the TextBlock go vertical), and have it aligned to the left side of the container.
I believe I understand how to make a TextBlock go vertical using RenderTransform or LayoutTransform. However, I cannot seem to get the 'docking' to work properly, whenever I change the vertical aspect of the container the TextBlock increases in horizontal aspect instead of vertical.
Here is what I have:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="AttendanceTracker.StudentView"
x:Name="UserControl" Height="172.666" Width="417.333">
<StackPanel x:Name="LayoutRoot" Orientation="Horizontal">
<Border BorderBrush="Black" BorderThickness="1" RenderTransformOrigin="0.5,0.5" Background="#52FFFFFF" Width="139.667">
<TextBlock Text="My Title" TextWrapping="Wrap" FontSize="18.667" TextAlignment="Center" Foreground="White" Margin="-58.509,68.068,49.158,70.734" Background="Black" RenderTransformOrigin="0.5,0.5" Width="147.017" d:LayoutOverrides="Height">
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-90"/>
<TranslateTransform/>
</TransformGroup>
</TextBlock.RenderTransform>
</TextBlock>
</Border>
</StackPanel>
Change the height of the UserControl and you will notice that the TextBlock increases in horizontal aspect instead of the desired vertical aspect.

If I understand you correctly, then this should point you in the right direction:
<StackPanel Orientation="Horizontal">
<TextBlock Background="Red" Text="My Title">
<TextBlock.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="90"/>
</TransformGroup>
</TextBlock.LayoutTransform>
</TextBlock>
</StackPanel>
The key is to use LayoutTransform, not RenderTransform. This will ensure that another layout pass occurs after the transform occurs. Otherwise, the layout system is using the original bounding rectangle to layout the TextBlock.
Beyond that, I just got rid of all the Blend-generated cruft to see what was going on. Here's the result:
alt text http://img187.imageshack.us/img187/1189/screenshottbv.png

Related

ScaleTransform on an image leaves whitespace

I'm creating a dialog with a single image, and a polygon overlaid. The problem is that the scale of the image is different from that of the polygon, so I want to scale the image down to match the scale of the polygon. But when I use the RenderTransform/ScaleTransform tags, the image gets sized down leaving whitespace at the right and bottom of the dialog. Yes the overlay now works properly, but I'd like to have it fill the available space to fill the window.
<Window x:Class="vw.CollImage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Collection Image" Height="700" Width="700"
WindowStartupLocation="CenterOwner" Grid.IsSharedSizeScope="False"
Icon="Resources\ty.ico">
<Viewbox MinWidth="70" MinHeight="70">
<Grid>
<Image Name="imgColl" HorizontalAlignment="Left" VerticalAlignment="Top" Source="{Binding ImageData}">
<Image.RenderTransform>
<ScaleTransform ScaleX="0.75" ScaleY="0.75"/>
</Image.RenderTransform>
</Image>
<Polyline Stroke="OrangeRed" StrokeThickness="6" Points="{Binding Coordinates}"/>
</Grid>
</Viewbox>
</Window>
Apply it as LayoutTransform instead.

RotateTransform on an Ellipse within a PivotItem

I'm new to WPF/Silverlight and I'm just playing about with my new Windows Phone 7.
I created a new Pivot application and changed it to the following code:
<Grid x:Name="LayoutRoot" Background="Transparent">
<!--Pivot Control-->
<controls:Pivot Title="MY APPLICATION">
<!--Pivot item one-->
<controls:PivotItem Header="first">
<Ellipse Width="300" Height="300" Fill="Red">
<Ellipse.RenderTransform>
<RotateTransform CenterX="150" CenterY="150" Angle="90"/>
</Ellipse.RenderTransform>
</Ellipse>
</controls:PivotItem>
<controls:PivotItem Header="second">
<Ellipse Width="300" Height="300" Fill="Blue"/>
</controls:PivotItem>
</controls:Pivot>
</Grid>
On the first pivot item, if you start your swipe over the ellipse, it is necessary to swipe upwards to move to the next pivotitem. If you begin the swipe somewhere outside of the ellipse, the swipe gesture is left right as expected.
I'm pretty sure that this is will be obvious to a XAML veteran, I'm not really sure how I should be preventing the gesture being affected by the RotateTransform too?
Any help appreciated.
Edit:
I think that I have figured this out. If I set IsHitTestVisible="False" on the Ellipse then it all works as expected.

Silverlight: Centering After ScaleTransform

I learned how to get a ScrollViewer's scrollbars to display after scaling an element within in a ScrollViewer from this post: http://www.eightyeightpercentnerd.dreamhosters.com/?p=92
Now, I'm trying to get the scaled object (a canvas in this case) to center correctly within the ScrollViewer. I'm going to let images tell my story here (please help me before Screencast.com purges my files). ;
My XAML:
<ScrollViewer x:Name="ScrollViewer" VerticalAlignment="Top"
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
Width="300" Height="300" Margin="0" Padding="0" Background="White">
<Canvas x:Name="DesignSurface" Background="Red">
<Canvas x:Name="Surface" Background="Blue" Height="100" Width="100">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="SurfaceScaleTransform" />
</TransformGroup>
</Canvas.RenderTransform>
<!-- ... -->
</Canvas>
</Canvas>
</ScrollViewer>
On initial load, my blue canvas is centered and at 100%:
After decreasing by 50%, the blue canvas is still centered:
After increasing 400% and scrolling to display the top left corner of the blue canvas:
After increasing 400% and scrolling to display the bottom right corner of the blue canvas:
So my question is simply how do I get the blue canvas centered correctly in the ScrollViewer or red canvas or whatever?
Maybe I got you wrong, but have you tried setting RenderTransformOrigin to the Canvas? E.g.:
<Canvas x:Name="Surface" Background="Blue" Height="100" Width="100"
RenderTransformOrigin="0.5, 0.5">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="SurfaceScaleTransform" />
</TransformGroup>
</Canvas.RenderTransform>
<!-- ... -->
</Canvas>

Use UIElement as Clip in WPF

Please pardon my ignorance- I'm very new to WPF.
I am looking to implement a minor, visual effect in my application that gives the look of "inner" rounded corners. The window in question has a dark border that encapsulates several UIElements, one of which is a StatusBar, located at the bottom of the window. This StatusBar has a dark background that matches the window's border. Above the StatusBar is a content view, which is currently a Grid- its background is semi-transparent (I think that this is something of a constraint- you can see through the content view to the desktop below). I would like for the content view (represented by the transparent, inner area in the figure below) to have the look of rounded corners, though I expect to have to sort of create the illusion myself.
(Can't post the image because I'm a lurker and not a poster- please find the drawing here)
My first approach was to add a Rectangle (filled with the same, dark color as the border) immediately above the StatusBar and to assign a Border with rounded corners to its OpacityMask (similar to the solution proposed by Chris Cavanagh**). Sadly, the effect that is produced is the exact opposite of that which I am trying to achieve.
I understand that the Clip property can be of use in this sort of situation, but it seems to me that using any sort of Geometry will prove to be inadequate as it won't be dynamically sized to the region in which it resides.
EDIT: Including my XAML:
<Grid Background="{StaticResource ClientBg}" Tag="{Binding OverlayVisible}" Style="{StaticResource mainGridStyle}">
<DockPanel LastChildFill="True">
<!-- Translates to a StackPanel with a Menu and a Button -->
<local:FileMenuView DockPanel.Dock="Top" />
<!-- Translates to a StatusBar -->
<local:StatusView DockPanel.Dock="Bottom" />
<!-- Translates to a Grid -->
<local:ContentView />
</DockPanel>
</Grid>
Any pointers are more than welcome- I'm ready to provide more indepth detail if necessary.
** http://www.dotnetkicks.com/wpf/WPF_easy_rounded_corners_for_anything
EDIT: Now I got what you mean. In fact you can use Path + OpacityMask approach. You have to draw "inverted" path, to use it as opacity mask. But I have simpler and faster solution for you :). Use Border + CornerRadius, and fill the gaps with solid paths. Just try the following code in Kaxaml and let me know if this is what you were looking for:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="240"
Height="320"
AllowsTransparency="True"
Background="Transparent"
WindowStyle="None">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="24"/>
<RowDefinition Height="*"/>
<RowDefinition Height="24"/>
</Grid.RowDefinitions>
<Border Background="Black"/>
<Border Grid.Row="1" BorderBrush="Black" BorderThickness="5">
<Grid>
<Border Background="White" CornerRadius="0, 0, 5, 5" Opacity="0.7"/>
<Path
Width="15"
Height="15"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Data="M10,10 L5,10 L5,5 C4.999,8.343 6.656,10 10,10 z"
Fill="Black"
Stretch="Fill"/>
<Path
Width="15"
Height="15"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Data="M10,10 L5,10 L5,5 C4.999,8.343 6.656,10 10,10 z"
Fill="Black"
Stretch="Fill">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="-1"/>
<TranslateTransform X="15"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Grid>
</Border>
<Border Grid.Row="2" Background="Black"/>
</Grid>
</Window>
PS: You can simplify this solution by avoiding render transforms, but you got the idea.

Why is my text cropped?

When i try to add a text block to a border element, i only see part of the text. I rotate the text after adding it to the border and that is causing the problem. Increasing the width of the border fixes this issue. But, my border needs to be only 20 units wide.
alt text http://img257.imageshack.us/img257/1702/textcrop.jpg
What am i missing here?
<Border
Name="BranchBorder"
CornerRadius="0"
HorizontalAlignment="Left"
Width="20">
<TextBlock
Name="Branch"
FontSize="14"
FontWeight="Bold"
VerticalAlignment="Center">
<TextBlock.RenderTransform>
<RotateTransform
Angle="-90"/>
</TextBlock.RenderTransform>
Branch
</TextBlock>
</Border>
Try using LayoutTransform
<Border
Name="BranchBorder"
CornerRadius="0"
HorizontalAlignment="Left"
Width="20">
<TextBlock
Name="Branch"
FontSize="14"
FontWeight="Bold"
VerticalAlignment="Center">
<TextBlock.LayoutTransform>
<RotateTransform
Angle="-90"/>
</TextBlock.LayoutTransform>
Branch
</TextBlock>
</Border>
There are bunch of blog entries describing the difference between RenderTransform and LayoutTransform and here is a cool visual demo from Charles Petzold RenderTransformVersusLayoutTransform.xaml
It appears as though the text is inheriting the <border> transformations before the rotation transform has a chance to rotate it. This means that the text first gets cropped to 20 units wide, and then gets rotated -90 degrees.
While I don't have an actual solution, I can confirm that its order of transformations that's causing the issue.

Resources