Rotate the text inside a small grid/panel - wpf

<Label Grid.Row="1"
Height="70"
Margin="2"
Width="300"
Content="{l:Translate Key={x:Static l:MultistringTags.SHOW_MENU}}"
DockPanel.Dock="Bottom"
FontSize="20"
FontWeight="Bold"
Foreground="White">
<Label.RenderTransform>
<RotateTransform Angle="270" />
</Label.RenderTransform>
</Label>
Here I want to rotate the text, which is inside a grid and a grid column width equals with text height. In this case I see only part of text like if text was drawn without rotating cutted of by grid width, and rotated to required angle. I have tried panels, they give me same result.
Does anybody know some workaround to make it show all the text and I don't want to use image because text should be translatable.

I believe if you change it to set the LayoutTransform instead of RenderTransform, it will prevent the text from being cut off.
<Label.LayoutTransform>
<RotateTransform Angle="270" />
</Label.LayoutTransform>

Further to #nekizalb's answer stating that you should use a LayoutTransform, the reason that you would need to do that instead of using a RenderTransform is because of the timing at which each occurs... a LayoutTransform will affect results of layout.
From the UIElement.RenderTransform Property page on MSDN:
A render transform does not regenerate layout size or render size information. Render transforms are typically intended for animating or applying a temporary effect to an element. For example, the element might zoom when focused or moused over, or might jitter on load to draw the eye to that part of the user interface (UI).
From the FrameworkElement.LayoutTransform Property page on MSDN:
In contrast to RenderTransform, LayoutTransform will affect results of layout.
Example scenarios where LayoutTransform would be useful include: rotating elements such as menu components from horizontal to vertical or vice versa, scaling elements (zooming in) on focus, providing editing behavior, etc.

Related

WPF control origin point

After some investigation, I still can't find method to change origin of control.
So, I want just to place one square exactly in center of another square, without margins, so it will be completely independent of first square size.
Theoretically, it can be easily done with HorizontalAlignment and VerticalAlignment set to Center, since it automatically sets Margin of control to half of width and height of parent control. But it is not so simple.
Simplest way to describe problem is next picture
As you can see, margin is counted towards upper left corner. Which is what I call origin. The perfect solution is to change it to center of first square, but this is where I need help - how can I do that?
Point of origin applies when using a transform object, and attaching the transform to your control. It won't actually effect the behaviour of the margin or left, top properties. If using a transform to place your object, point of origin is very useful.
The top, left (if using cavas) and margin (if using say grid) help govern the "auto" placement by the parent control, and this in turn governs where point of origin for the control winds up being relative to the parent control. The transform object then offsets RELATIVE to where that point of origin is.
The other useful thing is that transform overrides the auto placement in the parent control, or rather, forces an offset to where the parent wants to put it, which in some cases is useful - i.e., you might have boxes listed in a grid and want them to "shake" left and right when you hover the mouse over them, their alignment stays in order to the grid, but the transform lets you bump them away from their "forced" position.
For example, attach the same transform object to 2 controls, and set their origins separate, then apply an animation to the transform object - both controls will animate off the one animation object (if you wanted to their movement in perfect sync).
Well, it was weird enough. The given behaviour can be seen only when using Image, and Center alignment. Can be solved by either wrapping Image in Grid, which will be using Center alignment, or using Stretch alignment with Image (which is much simplier).
<Grid Width="500" Height="500">
<Image Width="250" Height="250" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</Grid>
If you want to reproduce problem I've described in question, replace Stretch with Center in code above.
Probably oversimplifying here but I would just use a Grid to wrap the two items you mentioned like this example (One stretched to fit and one centered):
<Grid>
<Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Black" BorderThickness="10" Margin="4"/>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Padding="10">InnerButton</Button>
</Grid>

Scrollviewer & Canvas

I am trying to load an image within a canvas such that, if the size of image overflows the canvas, the scroll bars should get activated (MS Paint style)
<Window>
<ScrollViewer>
<Canvas ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<Image Source="SampleImage.jpg" />
</Canvas>
</ScrollViewer>
</Window>
Now as Canvas is stretched to Window's size, scroll-bars won't appear as Canvas is not actually overflowing out of the Window.
Secondly, as the Image is much bigger than the Canvas, it is getting clipped at the bounds of Canvas, so ScrollViewer doesn't think that its content: Canvas is actually overflowing.
It happens a lot of time with StackPanels too, that even though the bound data has tens of rows, but still the scrollbars don't get activated. Sometimes scrollviewers appear as mystery to me.
So, what should be the basic logic kept in mind when using ScrollViewer control.
Thank you.
Edit: Just edited the question title, so that whosoever has problem with canvas can get this question easily in search.
From MSDN:
Canvas is the only panel element that has no inherent layout characteristics. A Canvas has default Height and Width properties of zero, unless it is the child of an element that automatically sizes its child elements. Child elements of a Canvas are never resized, they are just positioned at their designated coordinates. This provides flexibility for situations in which inherent sizing constraints or alignment are not needed or wanted. For cases in which you want child content to be automatically resized and aligned, it is usually best to use a Grid element.
Hovever, you can set Canvas Height and Width explicitely:
<ScrollViewer Height="100" Width="200">
<Canvas Height="400" Width="400">
//Content here
</Canvas>
</ScrollViewer>
Maybe one of these two Links might help you:
Silverlight Canvas on Scrollviewer not triggering
ScrollBars are not visible after changing positions of controls inside a Canvas

Image to not cause a row size change

I have a simple Grid with three columns. In one of these rows, I have (in column order): A TextBlock, a TextBox, and a Button. The Button contains an Image for it's content.
My issue is that the Image always sizes to display it's full content which enlarges the button. I don't care what size the image's source is; I want the Button to be the same size as the row already is due to the TextBlock and the TextBox. I don't want to specify a hard coded value for the image size. That's not the point. If a user's theme and/or font changes, the Grid row should still work as expected and the Button should always be the correct size.
I've tried a ViewBox, all sorts of alignment properties and bindings. No luck. Any ideas anyone?
<TextBlock VerticalAlignment="Center" Margin="4,0" x:Uid="RONumber" />
<TextBox x:Name="tbRO" InputScope="Number" MaxLength="8" Grid.Column="1" Margin="4" />
<Button x:Name="btnSearch" Click="Search_Click" Grid.Column="2">
<Image Source="Long Source Removed For Readability" />
</Button>
In the image below you can see the TextBox and to the right the Button with the Image inside it. Right below it is another TextBox which is correctly sized. And if I remove the button the top TextBox sizes the same.
Ok, so here's the answer. Because the elements are in the same row the XAML is not working. The binding I had made (before I even posted this question) to the ActualHeight always was 0. I instead bound the MaxHeight of the button to the ActualHeight of a random TextBox on another area of the screen. This worked.

WPF: how to write text in a different direction?

I need to write text in the orientation specified for the image below. The fact is that I saw some examples around here by using a textblock and rotating the angle of the control using "RenderTransform", but this is not what I really need. I tried to do it using an image but it doesn't fit very well... so I really don't know how to solve it. If you look at the image beside you can see that the text is written from bottom to top and the line below the text is in the right of the screen.
This is the screen that I need to develop:
I tried by rotating the textblock, but the only way that it works for me was wrapping the text, but this is just the "closest" solution that I found. Also, as you can see, I need to set a border for the textblock.
Anyway, I hope you can help me because any example around fits with my problem.
In order to rotate your text at 90 degrees, I believe that you will need to use the LayoutTransform instead of the RenderTransform:
<TextBlock Text="FootRoller" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
The difference is when the transform will be applied. Using the LayoutTransform, the text will be rotated before the layout pass and this will be important in your case. I imagine that using the RenderTransform will rotate your TextBlock, but as it does that after the layout pass, it would not show it all... this is because it was measured for size before it was rotated.
You can find out full details from the Transforms Overview page on MSDN. From the linked page:
LayoutTransform – A transform that is applied before the layout pass. After the transform is applied, the layout system processes the transformed size and position of the element.
RenderTransform – A transform that modifies the appearance of the element but is applied after the layout pass is complete. By using the RenderTransform property instead of the LayoutTransform property, you can obtain performance benefits.
They're all right. RenderTransform should be all you need. Like;
<TextBlock Text="FootRoller" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock.RenderTransform>
<CompositeTransform Rotation="-90"/>
</TextBlock.RenderTransform>
</TextBlock>
P.S. - You can literally just change RenderTransform to LayoutTransform which Sheridan has provided an explanation for in his answer.
If RenderTransform didn't work, take a look at LayoutTransform. You didn't tell us why RenderTransform didn't work but it's usually a safe bet that LayoutTransform will solve whatever problem it gave you.

In WPF, What is the best way to create toolbar buttons so that the images are properly scaled?

Specifically, I'm looking to use the 16*16 32-bit png images included with the VS2008ImageLibrary. I've tried manually setting the Height and Width attributes of the image, adjusting margins and padding, adjusting Stretch and RenderOptions. My attempts to create toolbar buttons have all led to either Improper Scaling (blurry icons), the bottom row of pixels on the icon being truncated, or the toolbar button being improperly sized - not to mention the disappearing icons already mentioned Here. Has anyone found the best way to make standard, VisualStudio/WinForms-style toolbar buttons that display properly in WPF?
First, change the image resolution to 96DPI, this can done with the free Paint.net ( http://www.getpaint.net ) by opening the file, Selecting Image->Canvas Size from the menu and adjusting the "resolution" to 96 and saving.
If this doesn't help you can then use the solution I wrote about in my blog here http://www.nbdtech.com/blog/archive/2008/11/20/blurred-images-in-wpf.aspx
Best way would be using Vector graphics instead of png. I know the following is not exactly what you asked for, but imho there is no way for better looking icons. Also it would help you get rid off margins and paddings. (Ok, if you want to use photos you're screwed)
Bad News is you probably need to repaint all your icons. You could do this using MS Expression Blend(it's capable to save painted Images as .xaml) or you make them on our own with a texteditor.
I prefer the Border.Background instead of the Image.Source for placing the icon, this allows me to put text over the image. This would look samething like that:
<Window.Resources>
<ResourceDictionary Source="Resources/Icons.xaml"/>
</Window.Resources>
<!--
...
-->
<Button>
<Border Background="{StaticResource IconName}" Height="16" Width="16" />
</Button>
The best workaround I can come up with is this:
<Image x:Key="TB_NewIcon" Source="Toolbar Images/NewDocumentHS.png" Height="16" Width="16" SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="NearestNeighbor"/>
...
<Button Command="ApplicationCommands.New" Content="{StaticResource TB_NewIcon}" Padding="2,2,2,1"/>
Or Alternatively:
<BitmapImage x:Key="TB_NewIcon" UriSource="Toolbar Images\NewDocumentHS.png"/>
...
<Button Command="ApplicationCommands.New" Padding="2,2,2,1">
<Image Source="{StaticResource TB_NewIcon}" Height="16" Width="16" SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="NearestNeighbor"/>
</Button>
For the Button Tag, the Padding attribute is needed to ensure that the image isn't truncated at a height of 15 pixels, and that the button isn't resized to fit the image. Alternatively, we could specify Padding="1", but then we must manually set Height="21" and Width="22" to ensure the button isn't resized to fit the image
On the Image Tab, the Height and Width are needed to ensure that the image isn't stretched. SnapsToDevicePixels and RenderOptions.BitMapScalingMode are both needed to ensure that there is no blurring. I can't promise that this will work nicely for all resolutions.
Note:
For the NewDocumentHS.png icon, the one that causes the most issues,as it takes up the full 16 pixels of height, you may want to adjust the padding to "1,1,3,2", so that the bottom aligns more properly with other icons.
You may want to consider trying a new property available now in WPF4.
Leave the RenderOptions.BitmapScalingMode to HighQuality or just don't declare it.
On your root element (i.e. your main window) add this property: UseLayoutRounding="True".
A property previously only available in Silverlight has now fixed all Bitmap sizing woes. :)
Please Note - a few of the effects layout rounding
can have on exact layout:
width and or height of elements may grow or shrink by at most 1 pixel
placement of an object can move by at most 1 pixel
centered elements can be vertically or horizontally off center by at most
1 pixel
More info found here: http://blogs.msdn.com/text/archive/2009/08/27/layout-rounding.aspx

Resources