winrt usercontrol got clipped on animation - xaml

adding usercontrol out of bounds of view and animating it with storyboard translate transform x from right corner gets the usercontrol view get clipped
here is xaml code for animation
<Storyboard x:Name="gridstory">
<DoubleAnimation
Storyboard.TargetName="gdd"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
From="0" To="-200" />
</Storyboard>
<Storyboard x:Name="gridstory2">
<DoubleAnimation
Storyboard.TargetName="gdd"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
From="-200" To="0" />
</Storyboard>
</UserControl.Resources>
am adding the usercontrol like this
c2.Margin = new Thickness(1355, 0, 0, 0);

The 1355 in your margin means the control will be laid out in the bounds of a rectangle that has the left border 1355 logical pixels away from the left border of its parent. On most screens that means that the layout rectangle is almost empty if not negative size, so it will usually get clipped. The solution might be to leave the Margin set to 0 and set HorizontalAlignment to Right and animate from c2.ActualWidth to 0 instead of 0 to -200.
Also check this article for something that might help you:
Animating edge-based UI

Related

canvas bottom missing uwp

I have a Canvas /RelativePanel which I'm using as background "image" in my uwp app.
How can I position a child in the canvas at the bottom? There is no canvas.bottom AP like in wpf. I also didn't find any proper attached property in the relativepanel to position the child at the bottom of the relative panel.
<RelativePanel>
<ContentControl ContentTemplate="{StaticResource AsterioidTemplate}" />
<Canvas x:Name="mountain_to_bottom" HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
<Path Width="126.389" Height="326.227" Canvas.Left="272.433" Canvas.Top="28.3291" Stretch="Fill" StrokeThickness="1.33333" StrokeLineJoin="Round" Stroke="#FF23232D" Fill="#FF23232D" Data="F1 M 398.155,353.889L 273.099,186.024L 315.298,28.9958L 398.155,353.889 Z "/>
</Canvas>
</RelativePanel>
How can I position a child in the canvas at the bottom?
Canvas is a layout panel that supports absolute positioning of child elements relative to the top left corner of the canvas in uwp.You control the positioning of elements inside the Canvas by specifying x and y coordinates.Since canvas is absolute positioning , child content is not constrained by the bounds of the panel, so we may not define the child at the bottom of canvas directly. But we can try to calculate the position manually to let the child position at the bottom of canvas. For example, the following demo can show the image at the bottom of the canvas.
XAML Code
<Canvas Background="Pink" x:Name="mountain_to_bottom" Height="600">
<Path x:Name="pathelement" Width="126.389" Height="326.227" VerticalAlignment="Bottom" Stretch="Fill" StrokeThickness="1.33333" StrokeLineJoin="Round" Stroke="#FF23232D" Fill="#FF23232D" Data="F1 M 398.155,353.889L 273.099,186.024L 315.298,28.9958L 398.155,353.889 Z "/>
</Canvas>
<Button x:Name="btnbottom" Click="btnbottom_Click" Content="to bottom"></Button>
Code behind
private void btnbottom_Click(object sender, RoutedEventArgs e)
{
double canvasheight = mountain_to_bottom.ActualHeight;
if (pathelement.ActualHeight < canvasheight)
{
double top = canvasheight - pathelement.ActualHeight;
pathelement.SetValue(Canvas.TopProperty, top);
}
}
I also didn't find any proper attached property in the relativepanel to position the child at the bottom of the relative panel.
Inside relative panel, elements are positioned using a variety of attached properties. Relative panel provides RelativePanel.AlignBottomWithPanel attached property for position the child at the bottom of the panel.
<RelativePanel BorderBrush="Gray" BorderThickness="10">
<Path x:Name="pathelement" RelativePanel.AlignBottomWithPanel="True" Width="126.389" Height="326.227" VerticalAlignment="Bottom" Stretch="Fill" StrokeThickness="1.33333" StrokeLineJoin="Round" Stroke="#FF23232D" Fill="#FF23232D" Data="F1 M 398.155,353.889L 273.099,186.024L 315.298,28.9958L 398.155,353.889 Z "/>
</RelativePanel>
If canvas and relative panel can not meet your requirements well you can consider about other containers. What container to use depend on your layout. For example, relativePanel is a layout container that is useful for creating UIs that do not have a clear linear pattern; that is, layouts that are not fundamentally stacked, wrapped, or tabular, where you might naturally use a StackPanel or Grid. More details please reference Layout panels.

VisualState AdaptiveTrigger MinWindowWidth=2160 doesn't work

AdaptiveTrigger with MinWindowWidth=2160 doesn't seems to work. I need it to handle Microsoft Surface Pro 3 screen resolution (2160x1440).
Look at this simple code below:
<Page
x:Class="TestUWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestUWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="2160" d:DesignHeight="1440">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="2160" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="brdMain.Background" Value="#bbbbbb"></Setter>
</VisualState.Setters>
</VisualState>
<VisualState>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="brdMain.Background" Value="#303030"></Setter>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="brdMain">
<TextBlock Text="Testing"></TextBlock>
</Border>
</Grid>
</Page>
You will see, the background colour is always black (#303030). Is there a maximum Width that VisualState can handle? Any idea?
Thanks
You have to remember that measurements in UWP are done in effective pixels (epx). See MSDN. Surface Pro 3, like other Surface tablets, has HiDPI display and a default scale factor greater than 1 which means that its effective pixel resolution is smaller than 2160x1440 even though that is its native resolution.
The SP3's default scale factor is 150%, resulting in an epx resolution of 1440x960. So even if you maximize your window, the window width is only at most 1440 epx, which means the MinWindowWidth="2160" state trigger will never fire on an SP3 with default settings.
If you want your state trigger to fire only on tablets with HiDPI displays and/or a certain native resolution, you will probably need to implement a custom state trigger that detects all of these conditions. How you do this is beyond the scope of this question.
I think your sizing might be off. Have you tried any others?
According to the Official MSDN Screen Sizes and Layouts Documentation these are the sizes that you want to use
The reason you probably don't want the exact screen size is because what's stopping someone from adjusting it down a little or up a little?
Personally, for more complex layouts, I prefer to create separate views for each size. It gives me more control over the layout. Here's how I use it.
In a static application level class I have.
public enum DeviceType
{
Desktop = 0,
Phablet = 1,
Mobile = 2
}
public static DeviceType CurrentDevice
{
get
{
ApplicationView view = ApplicationView.GetForCurrentView();
Rect rect = view.VisibleBounds;
if (rect.Width >= 1024)
{
return DeviceType.Desktop;
}
else if (rect.Width >= 720)
{
return DeviceType.Phablet;
}
else
{
return DeviceType.Mobile;
}
}
}
Then in my control I just access my static class in my Static Constructor. If I am a mobile device I load a mobile DefaultStyleKey. If I am desktop then I load a DesktopDefaultStyleKey.
DeviceType device = ApplicationServices.CurrentDevice;
switch (device)
{
case (DeviceType.Desktop):
YoutubeVideosPresenter.Content = new YouTubeVideosLayoutDesktop();
break;
case (DeviceType.Mobile):
YoutubeVideosPresenter.Content = new YouTubeVideosLayoutMobile();
break;
}
Of course this is not very "adaptive" if someone manipulates the window width. You can easily get past this though by checking to see if the window width has changed and then your style can easily be switched out.

set animation of opacity in vb.net in winrt

i have in winrt and xaml following code:
<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName="myImage"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:3"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
I want to convert this code to vb.net, so that I can set dynamically an animation to any image. My Problem is that in vb.net it seems that the line Animation.Storyboard.SetTargetName(xBewegung, "Opacity")
, where xBewegung is the doubleanimation, create an failure: WinRT-Informationen: Animation target not specified.
In some example I see something like new PropertyPath("Opacity"), but this seems not to work under winrt.
So what is the correct syntax.
Next Question: Is there anywhere a good source to see which strings I need, for example for a rotatetransform in need "Image.Angle", etc.
Thanks in advance, Basilius
You can set the animation target with a reference to the object:
Dim sb As New Storyboard()
Dim da As New DoubleAnimation()
da.From = 1
da.To = 0
da.Duration = New Duration(TimeSpan.FromSeconds(3))
da.AutoReverse = True
da.RepeatBehavior = RepeatBehavior.Forever
sb.Children.Add(da)
Storyboard.SetTarget(da, myImage) //myImage is the reference to the Image control
Storyboard.SetTargetProperty(da, "Opacity")
You probably have a reference. This way you do not have to handle the element names. The problem with .SetTargetName is WinRT's lack of NameScopes. Unforunately, I was not able to get it working. But SetTarget should be the better solution in many cases, anyway.

How to animate height of control in Windows 8 XAML

I'm having trouble performing a simple storyboard-based animation of a controls height in a Metro-style C#/XAML application on Windows 8.
The following trivial XAML and code behind snippets work fine in Silverlight 5 and Windows Phone 7, yet do nothing in Windows 8 (at least for me):
<Page.Resources>
<Storyboard x:Name="expandAnimation">
<DoubleAnimation Storyboard.TargetName="scaleButton" Storyboard.TargetProperty="Height" From="50" To="200" Duration="0:0:1"/>
</Storyboard>
</Page.Resources>
<StackPanel Width="200">
<Button x:Name="scaleButton" Click="scaleButton_Click" Content="Scale"/>
<Button Content="Another button"/>
<Button Content="Yet another button"/>
</StackPanel>
C# code:
private void scaleButton_Click(object sender, RoutedEventArgs e)
{
expandAnimation.Begin();
}
The same code can be altered to animate other properties of the control such as Opacity which works as expected.
I can animate a ScaleTransform to do the scaling, but it alters the internal rendering of the control, and does not affect the layout of neighbouring controls which is a problem for me.
Hopefully I'm not missing anything obvious here, but shouldn't this just work?
You just need to add EnableDependentAnimation="True" and then it should work fine.
A dependent animation is one that will cause the Xaml to re-layout. Expensive; therefore requiring an "opt-in".
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.media.animation.pointanimation.enabledependentanimation.aspx
If possible you should use a render transform and scale the element's visual instead. This is independent meaning that the rest of the elements on the page will not need to move to accommodate.

How to detect orientation changes and change layout?

Lets say that I have a grid with 2 rows, 2 columns and many controls inside each cell.
When the application is changed to snap mode, I meant 1/3 of the screen I would like the application to be only, one Column, 2 rows and show only some controls I would decide.
What kind of control do I have for this?
thx
You should make use of the VisualStateManager in xaml, for a full xaml solution:
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="OrientationStates">
<VisualState x:Name="Full"/>
<VisualState x:Name="Fill"/>
<VisualState x:Name="Portrait"/>
<VisualState x:Name="Snapped"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
Create StoryBoards for each VisualState and hide/show elements in your xaml. Microsoft examples use the same solution.
--
Update
I searched the net and found the proper states, an example is behind this link: MSDN.
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ApplicationViewStates">
<VisualState x:Name="FullScreenLandscape"/>
<VisualState x:Name="Filled"/>
<VisualState x:Name="FullScreenPortrait"/>
<VisualState x:Name="Snapped"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
The states reflect the ApplicationViewState enum. Even more information can be found here.
Using DisplayProperties.OrientationChanged event (as suggested by #Jan K.) may not be exactly what you are looking for, considering the remarks section to this event:
The DisplayProperties.OrientationChanged event occurs only when orientation of the display or monitor changes and not necessarily when the orientation of your app changes. To determine the orientation of your app for layout purposes, use the ApplicationView.Value property.
but since ApplicationView.Value probably will be abandoned after Windows 8.1 release MS suggest to use ApplicationView.GetForCurrentView() instead:
ApplicationView static methods may be altered or unavailable for releases after Windows 8.1 Preview. Instead, use ApplicationView.GetForCurrentView() to get an instance of ApplicationView.
So for now I've end up with that code (have a kind of dynamic view and can't pre-design everything in XAML via VisualStateManager, unfortunately):
public MainPage()
{
InitializeComponent();
Window.Current.SizeChanged += (sender, args) =>
{
ApplicationView currentView = ApplicationView.GetForCurrentView();
if (currentView.Orientation == ApplicationViewOrientation.Landscape)
{
// when args.Size.Width > args.Size.Height
}
else if (currentView.Orientation == ApplicationViewOrientation.Portrait)
{
// when args.Size.Width < args.Size.Height
}
};
}
Have a look on the DisplayProperties.OrientationChanged-Event. When it fires you can modify your grid and rearrange your controls.