Animation Shapes in UWP - c#

How can I use scale animation to scaling the Shapes like Path, Rectangle, ... without memory increasing.
It seems that UWP uses BitmapCache by default in Scale animation and this is because UWP tries to use BitmapCache for smooth animation but I think UWP can clip the BtimapCache to decrease memory usage.
Here is my simple code which builds in Windows10 v1903.
<Page.Resources>
<Storyboard x:Name="MyStoryboard" >
<DoubleAnimation To="{Binding MyScale}" Duration="0:0:0.3" Storyboard.TargetName="CompositeTransform"
Storyboard.TargetProperty="ScaleX"/>
<DoubleAnimation To="{Binding MyScale}" Duration="0:0:0.3" Storyboard.TargetName="CompositeTransform"
Storyboard.TargetProperty="ScaleY"/>
</Storyboard>
</Page.Resources>
<Grid Background="Transparent">
<Ellipse x:Name="path" Fill="Red" VerticalAlignment="Top" HorizontalAlignment="Left"
StrokeThickness="1" Stroke="#FF000000" Width="200" Height="100"
>
<Ellipse.RenderTransform>
<CompositeTransform x:Name="CompositeTransform" ></CompositeTransform>
</Ellipse.RenderTransform>
</Ellipse>
</Grid>
and C#:
private void MainPage_OnPointerWheelChanged(object sender, PointerRoutedEventArgs e)
{
if (e.GetCurrentPoint(this).Properties.MouseWheelDelta > 0)
MyScale *= 2;
else
MyScale /= 2;
MyStoryboard.Begin();
}
when the user uses the mouse wheel and tries to zoom-in, the memory is increasing.
Is there anything wrong with my code?
To simplify this question I'm going to compare UWP and WPF in big objects. so I create solutions in both UWP and WPF with just one shape in MainPage. Here are the solutions:
UWP:
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Rectangle Width="20000" Height="20000" Fill="Red" Stroke="Black" />
</Page>
WPF:
<Window x:Class="TestScaleBigPath.MainWindow"
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"
WindowState="Maximized" >
<Rectangle Width="20000" Height="20000" Fill="Red" Stroke="Black" />
</Window>
WPF only takes 53MB memory while UWP takes 950MB. Here are the Diagnostics Sessions:
UWP
WPF

Related

WPF Window Blur + Drop shadow

I've done some searching but I can't seem to find a way to use both a drop shadow on my window, and have the window's background blurred.
I'm currently using https://github.com/riverar/sample-win32-acrylicblur (all blur code in MainWindow.xaml.cs) to blur the background, but since the dropshadow requires some padding in the window to render the dropshadow in, the space of the dropshadow gets the blur applied to it too.
I tried using an OpacityMask, but that didn't seem to help. In fact, even when setting the Window's Opacity property to 0, the blur still showed, so I fear that it's not possible with this method of blurring.
One of the packages I already am using is Microsoft.Windows.Shell, which I need to rebuild the default buttons I lose after applying the drop shadow, perhaps this has something helpful.
TLDR:
Is there a way to use an Aero-style blurred Window and a drop shadow together? Ideally without installing extra packages, but if there's no other way I'll have to bite the bullet.
I'm on the latest versions of .Net etc. as of 03/08/2018
Do you mean the effect shown below?
If so, you can write the XAML code to get it.
<Window x:Class="Walterlv.Demo.MainWindow"
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" Title="MainWindow" Height="450" Width="800"
AllowsTransparency="True" WindowStyle="None" Background="{x:Null}">
<Grid>
<Rectangle x:Name="ShadowShape" Fill="White" Margin="8">
<Rectangle.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="0" />
</Rectangle.Effect>
</Rectangle>
<Border x:Name="BackgroundBorder" Margin="8" ClipToBounds="True">
<Rectangle x:Name="BlurringShape" Margin="-32">
<Rectangle.Fill>
<ImageBrush ImageSource="Sample.jpg"/>
</Rectangle.Fill>
<Rectangle.Effect>
<BlurEffect KernelType="Gaussian" Radius="32" />
</Rectangle.Effect>
</Rectangle>
<Border.CacheMode>
<BitmapCache />
</Border.CacheMode>
</Border>
</Grid>
<Grid>
<!-- Write your own content here... -->
</Grid>
</Window>
Notes:
I write three UIElement to implement that effect:
The BlurringShape renders a bitmap and blur itself. It blurs at the radius 32, so it should set a -32 margin to avoid the transparent blur.
The BackgroundBorder clips the BlurringShape so that the blur will not spill over.
Because we have clipped the BackgroundBorder, so if we set a DropShadowEffect on it, it will be clipped. We should create another shape to render the DropShadowEffect. That is the ShadowShape.
If you want your style more reusable, you can take this code below:
<Window x:Class="Walterlv.Demo.MainWindow"
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" Title="MainWindow" Height="450" Width="800">
<Window.Background>
<ImageBrush ImageSource="High+Sierra.jpg"/>
</Window.Background>
<Window.Style>
<Style TargetType="Window">
<Setter Property="AllowsTransparency" Value="True" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<Grid>
<Rectangle Fill="White" Margin="8">
<Rectangle.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="0" />
</Rectangle.Effect>
</Rectangle>
<Border x:Name="BackgroundBorder" Margin="8" ClipToBounds="True">
<Rectangle Margin="-32" Fill="{TemplateBinding Background}">
<Rectangle.Effect>
<BlurEffect KernelType="Gaussian" Radius="32" />
</Rectangle.Effect>
</Rectangle>
<Border.CacheMode>
<BitmapCache />
</Border.CacheMode>
</Border>
<ContentPresenter Margin="8" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Style>
<Grid>
<!-- Write your own content here ... -->
</Grid>
</Window>

Image disappears if not directly centered in window [Margin not "0"]

I've got a bit of a problem with my images in a WPF Vb.net based window.
If the image control is not directly in the centre of the window with a margin of 0, it will not show at runtime.
Here is the XAML code for both images:
<Image x:Name="loaderlogo" Height="55" Margin="1825,985,40,40" Width="55" Stretch="Fill"/>
<Image x:Name="tips" Height="128" Margin="0,732,0,220" Width="1920" Stretch="Fill" Opacity="0.9"/>
Both are contained inside a grid with one row and one column (the default grid that is there when you create a new window).
These images will not appear if this code is run however if i make the margins
Margin="0"
They will appear just fine, but in the very center of the control
How can i make it so that the controls still appear if the margins are not zero (if i move the images' location anywhere but the center of the form?
The code i use to fetch the image files is:
UseLayoutRounding = True
Dim exepath As String = System.AppDomain.CurrentDomain.BaseDirectory
loaderlogo.Source = New BitmapImage(New Uri(exepath & "loaderlogo.png", UriKind.Absolute))
tips.Source = New BitmapImage(New Uri(exepath & "tips.png", UriKind.Absolute))
The images work perfectly fine if dead center so I believe the problem is with the XAML but I am not sure where. I have changed the horizontal/vertical alignment but the images still appear in the center as long as the margin is 0.
EDIT: Below are the positions where I would like the controls to be, the bottom left is the 'loaderlogo' and the band across the window is the 'tips' control.
tips band position
loaderlogo position
EDIT 2: Below is the entire XAML code for the window:
<Window x:Class="loadingwindow" UseLayoutRounding="True"
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"
xmlns:local="clr-namespace:applicationname"
mc:Ignorable="d"
Title="loadingwindow" Height="1080" Width="1920" AllowsTransparency="True" WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" WindowState="Maximized" Loaded="Window_Loaded">
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="00:00:01" Storyboard.TargetProperty="Opacity" From="0" To="1" Completed="DoubleAnimation_Completed"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<Image x:Name="loaderlogo" Height="55" Margin="1825,985,40,40" Width="55" Stretch="Fill"/>
<Image x:Name="tips" Height="128" Margin="0,732,0,220" Width="1920" Stretch="Fill" Opacity="0.9"/>
</Grid>
Large margins are the worst way to position elements. The better approach is to use correct layout panel and correct alignments for elements. Small margin is fine to add some space between elements.
Grid panel is usually used with many RowDefinitions and ColumnDefinitions. Elements are placed in different rows and columns, and resulting layout is adaptive to size changes
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image x:Name="tips" Grid.Row="1" Height="128" Width="1920" Stretch="Fill" Opacity="0.9"/>
<Image x:Name="loaderlogo" Grid.Row="2" Height="55" Width="55" Margin="10"
HorizontalAlignment="Right" Stretch="Fill"/>
</Grid>

My content leaves my screen, how can I prevent this?

I am making a full-screen c# application, with WPF.
But my content is leaving my screen because i want the height and width of the application to be dynamic.
This is my current test:
<Window x:Class="examen.MainWindow"
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"
xmlns:local="clr-namespace:examen"
mc:Ignorable="d"
Background="#024886"
Title="MainWindow" WindowStyle="None" WindowState="Maximized" >
<Canvas>
<Rectangle Fill="#FBB510" Height="84" RadiusX="20" RadiusY="20" Stroke="Black"
VerticalAlignment="Bottom" MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"
Canvas.Left="248" Width="89" Canvas.Top="242"/>
</Canvas>
</Window>
How can I make sure the content will stay at its place?
Try this solution...
Suround all of your windows controls with a ViewBox....
<Viewbox>
<Canvas>
<Rectangle Fill="#FBB510" Height="84" RadiusX="20" RadiusY="20" Stroke="Black" VerticalAlignment="Bottom" MouseLeftButtonDown="Rectangle_MouseLeftButtonDown" Canvas.Left="248" Width="89" Canvas.Top="242"/>
</Canvas>
</Viewbox>

How can set absolute position on stackpanel or grid in xaml WPF

Is it possible to set my StackPanel or Grid to be position absolute like CSS.
In CSS is have property Position of the elements and can set to be relative, absolute and is working good.
In XAML can make Grid, StackPanel to use position absolute.
You have to use Canvas in order to set absolute position in WPF.
In case of buttons in a window, here is a sample :
<Window x:Class="tobedeleted.MainWindow"
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"
Title="MainWindow" Height="350" Width="525">
<Canvas>
<Button Canvas.Left="10" Canvas.Bottom="20">Bottom left</Button>
</Canvas>
</Window>
The output is :
Feel free to ask if help is needed.
Absolute positioning defeats the purpose of WPF, but I agree, sometimes there is no other way so you have two basic options.
Elements under the root grid
Elements in a canvas that is the same size as the window (as Vasilievski pointed out)
Code example:
<Window x:Class="WpfApplication1.Window3"
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"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="Window3" Height="300" Width="300">
<Grid>
<Rectangle Fill="Red" Width="100" Height="120"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Panel.ZIndex="13"
Margin="12,34"
/>
<Rectangle Fill="Green" Width="100" Height="120"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="24,54"
/>
<Canvas>
<Rectangle Canvas.Left="5" Canvas.Top="5" Panel.ZIndex="2" Fill="Yellow" Width="120" Height="30" />
<Rectangle Canvas.Left="25" Canvas.Top="17" Panel.ZIndex="0" Fill="Blue" Width="120" Height="30" />
</Canvas>
</Grid>
</Window>
try this.
<StackPanel>
<Canvas>
<TextBlock Canvas.Left="10" Canvas.Top="6" Text="Choose a value from combobox:" Width="180"/>
<ComboBox Canvas.Left="190" Canvas.Top="4" Width="180"></ComboBox>
</Canvas>
</StackPanel>
RESULT:

Xaml (Windows Phone 8 & Silverlight) usercontrol stacking issue

I have a usercontrol that I am placing in a grid. Inside the grid I am also drawing lines. These lines appear above the usercontrol like they should.
When the user clicks on my usercontrol, I am showing another part of the usercontrol, an xaml element (making it visible) and I need it to appear above the drawn lines.
I've tried Canvas.ZIndex. That seems to only work with elements inside my usercontrol. If I set the usercontrols ZIndex high, then it all appears above the lines.
Here is the Min working example:
I need the Blue square to stay below the black line and the yellow ellipse to be above the black line.
--Main Page--
<UserControl xmlns:SWE_UserControlOverlap="clr-namespace:SWE_UserControlOverlap" x:Class="SWE_UserControlOverlap.MainPage"
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"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<SWE_UserControlOverlap:SWE />
<Line Stroke="Black" StrokeThickness="10" Stretch="Fill" X1="0" Y1="0" X2="1" Y2="1"></Line>
</Grid>
</UserControl>
--UserControl--
<UserControl x:Class="SWE_UserControlOverlap.SWE"
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"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Rectangle Fill="Blue" MouseLeftButtonUp="Rectangle_MouseLeftButtonUp_1"></Rectangle>
<Ellipse Margin="100" Fill="Yellow" ></Ellipse>
</Grid>
</UserControl>
Don't set a ZIndex on the control, just modify it for the sub controls.
<Line Canvas.ZIndex="1" />
<Rectangle Canvas.ZIndex="0" />
<Ellipse Canvas.ZIndex="2" />
As I found in various spots on the web - this is just not possible.

Categories