wpf progressbar.RenderTransform outside of window in designer - c#

when I apply the 180 degree transform to the progress bar it goes outside of the window. here is what it looks like in the designer.
http://i.imgur.com/mZfJHXL.jpg
how can I get it to move inside the window.
here is my code:
<Window x:Class="game.Player2Screen"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Player2Screen" Height="298" Width="310">
<ProgressBar Name="ProgressBarTimer" Orientation="Vertical" Foreground="Blue" Background="Black" MouseLeftButtonDown="ProgressBarTimer_MouseLeftButtonDown"
Value="0" HorizontalAlignment="Center" Maximum="100" VerticalAlignment="Top" Height="250" Width="265" >
<ProgressBar.RenderTransform>
<RotateTransform Angle="180"/>
</ProgressBar.RenderTransform>
</ProgressBar>
</Window>

You need to specify the render transform origin.
See this MSDN article

Perhaps you want to use a LayoutTransform instead of RenderTransform.
The way WPF handles drawing components is:
LayoutTransform
Measure
Arrange
RenderTransform
Render
It sounds like you want to do your transformation before measuring and arranging the component, not after.

Related

DropShadowEffect with Semi Transparent Grid

I am trying to create a grid (with 30% opacity) and drop shadow from it. I have done a mock up in photoshop and this is what I want to achieve:
This is how I tried to implement it in xaml:
<Grid Background="#808080">
<Grid Width="100"
Height="100"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid Background="White"
Opacity="0.3">
<Grid.Effect>
<DropShadowEffect />
</Grid.Effect>
</Grid>
</Grid>
</Grid>
Unfortunately, this is how it turned out:
As you can see from the image above, the shadow effect can seen underneath the 30% grid. How do I remove the shadow effect within the grid and only make the shadow appear outside the grid (on the bottom right)?
Easy solution, drop the opacity. But I guess that would not be acceptable, so another solution which is more of a workaround.
Add a Border inside your inner grid and drop shadow on that border, also make the border thickness disappear on 2 sides on which you do not want the shadow. Something like this:
<Grid Background="White" Opacity="0.3">
<Border BorderBrush="White" BorderThickness="0,0,1,1">
<Border.Effect>
<DropShadowEffect />
</Border.Effect>
</Border>
</Grid>

How to get RelativePanel's Canvas.Top value in C# code?

I have code as below. Which puts a RelativePanel inside of a Canvas. And I apply animation onto the panel, which will move it down 230 pixels, i.e. to change its Canvas.Top="0" to Canvas.Top="230"
In the C# code, I need to detect whether the animation works. So I need to get the Canvas.Top of the RelativePanel.
But how?
Thanks!
<Canvas x:Name="toolbarCanvas" Margin="0,0,0,-50" Height="140" Width="1000" RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignHorizontalCenterWithPanel="True">
<RelativePanel x:Name="toolbarPanel" Margin="0,0,0,0" Canvas.Top="230">
<Image x:Name="toolbarBackground" Source="Assets/MainPage/toolbar/toolbar-background.png" Height="140" Width="1000" Stretch="Uniform" RelativePanel.AlignHorizontalCenterWithPanel="True" />
</RelativePanel>
</Canvas>
Since Canvas.Top is an attached property you can simply use:
var top = Canvas.GetTop(toolbarPanel);

Border around a rotating image

Basically I'm trying to do something whereby a WPF image is inside a WPF border, and periodically I rotate the image by changing the RotateTransform Angle property.
The problem is, when I rotate the image, the border doesn't rotate, or attempt to change to fit the new shape of the picture. I've tried setting it's Alignment properties to stretch, and even binding the height/width of the border to that of the image, but no luck. I suspect the problem is that, when I rotate the image, it doesn't actually change the height or width of the Image object, so of course the border doesn't know what to do.
Is there a better way to rotate the image that would allow the border to resize, or if not, how do I get the border to resize correctly, given that I'm changing the RotateTransform Angle.
Thanks!
You can use the LayoutTransform instead of RenderTransform for this. If you try changing the angle of rotation you'll see the border changes size to accommodate it. (Think this is what you're asking? If you actually want the border to rotate then you can just rotate that instead of the image)
<Window x:Class="rotate.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Border VerticalAlignment="Center" HorizontalAlignment="Center" BorderBrush="Black" BorderThickness="1">
<Grid Background="Blue" Width="80" Height="80">
<Grid.LayoutTransform>
<RotateTransform Angle="10"/>
</Grid.LayoutTransform>
</Grid>
</Border>
</Grid>
</Window>
Use LayoutTransform instead of RenderTranform.
RenderTransform only does a visual transformation of the control and is applied after measuring and arranging Controls. Therefore it doesn't affect the size seen by other controls.
LayoutTransform really affects the layout of the object. It's applied before measuring and arranging control, so the other control see a change in the size.
Caution: LayoutTransform is much slower and won't usually give a smooth animation.
<Border BorderThickness="5" BorderBrush="Red" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Width="50" Height="50">
<Image.LayoutTransform>
<RotateTransform Angle="45" />
</Image.LayoutTransform>
</Image>
</Border>

Resize WPF application

Have tried searching google but I'm struggling to find an answer to this.
I have a basic WPF application with a few controls on. When I maximise the application the controls on the screen stay the same size and I get a lot of wasted space.
Is there a way to get the controls to grow and shrink dynamically with the size of the main window?
Kind Regards
Ash
Don't set a fixed Height and Width properties for your controls.
Instead set, horizontal and vertical alignment to stretch. And make sure your controls are contained inside an appropriate layout panel.
For example-
Fixed size grid:
<Grid Background="Red" Width="50" Height="50"/>
Dynamically expending grid:
<Grid Background="Red" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
what you need is not resize, it's called scaling (or zooming) ;-)
Read this article; the task is very trivial with WPF.
(used to be much more complicated in Windows Forms...).
UI Scaling (UI Zooming) with WPF
basically all you need to add to the XAML is this:
<ScaleTransform
CenterX="0" CenterY="0"
ScaleX="{Binding ElementName=uiScaleSlider,Path=Value}"
ScaleY="{Binding ElementName=uiScaleSlider,Path=Value}"
/>
after that you can use mouse wheel or a slider or any other way (like in your case detect form maximized), to modify the Value of the ScaleTransform.
Where there's a will, there's a way. You will have to do some work yourself however, WPF can't automagically decide for you exactly how you want the resizing to be done.
Some relevant sources:
Layout containers
Data Binding
You can use content decorator that can stretch and scale a single child to fill the available space - Viewbox .
http://www.wpftutorials.com/2011/04/wpf-viewbox.html
this is no problem. The behavior of your controls depends on the container you use and the Horizontal and Vertical Alignment. For Example, if you use a Grid, a TextBox and a Button with Horizontal and Vertical Alignment: Stretch and width and height auto, the Textfield and Button will grow and shrink dynamically.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Grid x:Name="LayoutRoot">
<TextBox Margin="8,8,8,104.96" TextWrapping="Wrap" Text="TextBox" Height="auto" Width="auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<Button Content="Button" Margin="8,0,8,8" VerticalAlignment="Bottom" Height="92.96" Width="auto" HorizontalAlignment="Stretch"/>
</Grid>
Use a resizable control like Grid and put all the controls in Rows/Columns. Also set HorizontalAlignment to stretch for each control.

How to rotate a WPF Window?

Is it possible to rotate a WPF Window by 45 degree, using xaml?
First question: Why do you want to rotate the whole window?
If you really need it:
You can't rotate the normal WPF window. See: Rotate Window
You will have to create a borderless window and provide a UI to it. See: WPF Non-Client Area Design Techniques For Custom Window Frames
For rotated window look:
Set:
AllowTransparency property to
true.
WindowStyle to None to
remove window chrome
Background
to Transparent
Include a border (or anything meaningful like rectangle, circle, ellipse, etc.) as content of the window and following properties of border:
white background (or any non-transparent color)
rotate transformation, and
smaller size (so as to fit when rotated within the window).
Border will provide the UI to your window.
Be aware of cavaets of creating own borderless window, as it requires you to provide the window interface like minimise, maximise, close buttons; and may require some unmanaged code.
Also, in sample code below, the border when rotated has to be kept within the bounds of the window, otherwise it (and your custom window) will be trimmed.
Sample code
<Window x:Class="CustomWindowStyle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
AllowsTransparency="True" WindowStyle="None" Background="Transparent"
Title="MainWindow" Height="600" Width="600">
<Border BorderBrush="Green" BorderThickness="2" Background="White" Width="360" Height="360">
<Border.RenderTransform>
<RotateTransform Angle="-45" CenterX="180" CenterY="180"/>
</Border.RenderTransform>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="23" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="X" Height="23" Width="23" Name="button1" HorizontalAlignment="Right" VerticalAlignment="Top" Click="button1_Click"/>
<Grid Grid.Row="1">
<!--Main window content goes here-->
<TextBlock Text="Main window content goes here" HorizontalAlignment="Center" />
</Grid>
</Grid>
</Border>
</Window>
As far as I know you can't rotate an entire window, but you could put everything inside the window into a custom control and apply apply a RenderTransform object to the custom control.
Example (somewhat simple):
http://www.codeproject.com/KB/WPF/TransformationsIntro.aspx
-- Dan

Categories