Moving a XAML Element from One Postion to another - xaml

I took the following tutorial as a good start point to animation and also explored the toolkit Offset option but found it somehow complex to accomplish what I want, unless proven otherwise.
Goal:
Upon clicking a matrix button, move the object from its starting position to the position of the clicked button, then return the object back to its initial position.
Challenge: The main challenge might be in determining the exact position of each matrix element (Button); the element's position in regard to the Grid is pretty clear, for example Grid.Row="1" Grid.Column="2", but in regard to Canvas and animation in general...no idea!
According to the code below, how to move the EllipseFigure from square 6 to square 1?
<Canvas>
<Canvas.Resources>
<Storyboard x:Name="myStoryboard">
<!-- Animate the center point of the ellipse. -->
<PointAnimation EnableDependentAnimation="True" Storyboard.TargetProperty="Center"
Storyboard.TargetName="EllipseFigure"
Duration="0:0:5"
From="1,2"
To="0,0"
RepeatBehavior="Forever" />
</Storyboard>
</Canvas.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="Button">
<Setter Property="BorderBrush" Value="Yellow" />
<Setter Property="BorderThickness" Value="5" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
</Style>
<Style TargetType="TextBox">
<Setter Property="BorderBrush" Value="Yellow" />
<Setter Property="BorderThickness" Value="5" />
</Style>
</Grid.Resources>
<Button Grid.Row="0" Grid.Column="0" Content="1" />
<Button Grid.Row="0" Grid.Column="1" Content="2" />
<Button Grid.Row="0" Grid.Column="2" Content="3" />
<Button Grid.Row="1" Grid.Column="0" Content="4" />
<Button Grid.Row="1" Grid.Column="1" Content="5" />
<Button Grid.Row="1" Grid.Column="2" Content="6" />
<Path Grid.Row="1" Grid.Column="2" Fill="Blue" PointerPressed="ButtonClick">
<Path.Data>
<!-- Describe an ellipse. -->
<EllipseGeometry x:Name="EllipseFigure"
Center="20,20" RadiusX="15" RadiusY="15" />
</Path.Data>
</Path>
</Grid>
</Canvas>
CodeBehind:
private void ButtonClick(object sender, RoutedEventArgs e)
{
myStoryboard.Begin();
}

Using the Storyboard approach you have, you can accomplish this by getting the position of the button and the ball and set the To property of the animation. You can also return the ball by setting AutoReverse to true
<Storyboard x:Name="myStoryboard">
<PointAnimation Storyboard.TargetProperty="Center"
Storyboard.TargetName="EllipseFigure"
Duration="0:0:1"
AutoReverse="True"
EnableDependentAnimation="True"/>
</Storyboard>
Make sure you subscribe to the Click event of the buttons and not the PointerPressed of the ball.
private void Button_Click(object sender, RoutedEventArgs e)
{
var button = (Button)sender;
// Get the position (top left) of the Button
GeneralTransform transform = button.TransformToVisual(this);
Point buttonPosition = transform.TransformPoint(new Point(0, 0));
// Get the center of the button
Point buttonCenter = new Point(buttonPosition.X + (button.ActualWidth / 2), buttonPosition.Y + (button.ActualHeight / 2));
// Get the position of the ball
transform = Ball.TransformToVisual(this);
Point ballPosition = transform.TransformPoint(new Point(0, 0));
// Get the center of the ball
Point ballCenter = new Point(ballPosition.X + (EllipseFigure.Center.X), ballPosition.Y + (EllipseFigure.Center.Y));
// The animation acts like it's at 0,0. calculate position to go to
Point to = new Point(buttonCenter.X - ballCenter.X, buttonCenter.Y - ballCenter.Y);
var storyBoard = (Storyboard)Root.Resources["myStoryboard"];
var animation = (PointAnimation)storyBoard.Children[0];
animation.To = to;
storyBoard.Begin();
}
Note that I give your Path element an x:Name of "Ball"

Related

Segmented control Xamarin Forms customisation

I would like to create the segmented control in the image below.
What i currently have or attempted using is the library in the following link : https://github.com/1iveowl/Plugin.SegmentedControl
How ever as you can see the final result ends up being a horizontal segmented UI, which is what I do not want.
I have checked the documentation of the plugin to see if there is a way of changing the orientation and it seems that is the current limitation of the plugin
<control:SegmentedControl
x:Name="SegmentedGenderControl"
TintColor="#F2EBF9"
SelectedTextColor="#6F1AC1"
TextColor="Black"
DisabledColor="White"
BorderColor="#6F1AC1"
BorderWidth="1.0"
FontSize="Medium"
Margin="8,8,8,8">
<control:SegmentedControl.Children >
<control:SegmentedControlOption Text="Male"/>
<control:SegmentedControlOption Text="Female"/>
<control:SegmentedControlOption Text="Female"/>
</control:SegmentedControl.Children>
</control:SegmentedControl>
The second alternative that I have thought about is using a grid with 3 rows :
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
</Grid>
And then manually handle the selection based on the selection. Is there a simpler or plugin that is available to the public that is not the one above that I can use ?
So I finally managed to solve this problem as suggested by an external party through the use of a collection view
See the code that follows :
<CollectionView
HeightRequest="250"
x:Name="OptionsCollectionView"
ItemsSource="{Binding SelectionOptions}"
VerticalOptions="Start"
SelectionMode="Single">
<CollectionView.ItemTemplate>
<DataTemplate>
<yummy:PancakeView
x:Name="optionPancake"
Padding="20">
<yummy:PancakeView.Border>
<yummy:Border
Color="{StaticResource CollectionViewBorderColor}"
Thickness="2" />
</yummy:PancakeView.Border>
<StackLayout
Orientation="Horizontal">
<Label
x:Name="optionLabel"
Text="{Binding Option}"
FontSize="15"
FontFamily="EuclidCircularASemibold"
TextColor="{StaticResource SubHeadingColor}"
FontAttributes="Bold" />
</StackLayout>
</yummy:PancakeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
The code that follows is for styling the visual state group, when an item is selected:
<Style TargetType="yummy:PancakeView">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<VisualState Name="Normal"/>
<VisualState Name="Selected">
<VisualState.Setters>
<Setter
Property="BackgroundColor"
Value="{StaticResource FrameSelectedColor}"/>
<Setter
Property="yummy:PancakeView.Border"
Value="{yummy:BorderMarkup Color={StaticResource SelectedLabelColor}, Thickness='2'}"/>
<Setter TargetName="optionLabel"
Property="Label.TextColor"
Value="{StaticResource SelectedLabelColor}"/>
<Setter Property="CornerRadius"
Value="5"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>

Animating Xaml Grid.ColumnDefinitions using XAML Behaviors when Binding Changes

I have a grid showing data received from a web service as below:
The graph bars are achieved using data binding, with the converter returning a GridLength Star value:
<Grid Grid.Row="1" BorderThickness="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="{Binding home.possessionPercentage, Converter={StaticResource statswidthConverter}}"/>
<ColumnDefinition Width="3"/>
<ColumnDefinition Width="{Binding away.possessionPercentage, Converter={StaticResource statswidthConverter}}"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="tbl1" HorizontalAlignment="Center" TextWrapping="Wrap" Text="{Binding home.possessionPercentage}"/>
<Rectangle Fill="#FF1DEE00" Stroke="White" Grid.Column="1" StrokeThickness="0"/>
<Rectangle Fill="White" Stroke="White" Grid.Column="2" StrokeThickness="0"/>
<Rectangle Fill="#FF139D00" Stroke="White" Grid.Column="3" StrokeThickness="0"/>
<TextBlock x:Name="tbr1" HorizontalAlignment="Center" TextWrapping="Wrap" Text="{Binding away.possessionPercentage}" Grid.Column="4"/>
</Grid>
What I would like to achieve is for the column sizes to be animated to the new value when the binding value is updated rather than just a jump to the new size. I believe this can be achieved with the Microsoft.Behaviors library - https://github.com/Microsoft/XamlBehaviors/ but am unsure where to start. Any advice please?
To meet your requirements, firstly you need an animation to animate the Width property. I wrote a simple demo which use DoubleAnimation to animate the Width of the Rectangle. For the reason I set the target of storyboard to Rectangle is that ColumnDefinition.Width property is GridLength type that we cannot use DoubleAnimation.
Secondly, we need a trigger to trigger the animation. Here I use DataTriggerBehavior in XamlBehaviors SDK. Once the data greater than one value the trigger can be triggered.Completed demo as follows.
<Page
...
xmlns:Interactions="using:Microsoft.Xaml.Interactions.Core"
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:Media="using:Microsoft.Xaml.Interactions.Media">
<Page.Resources>
<local:statswidthConverter x:Name="statswidthConverter" />
<Storyboard x:Name="Increase">
<DoubleAnimation
Duration="0:0:5"
EnableDependentAnimation="true"
Storyboard.TargetName="rec1"
Storyboard.TargetProperty="Width"
To="{Binding homePercentage, Converter={StaticResource statswidthConverter}}" />
</Storyboard>
<Storyboard x:Name="decrease">
<DoubleAnimation
Duration="0:0:5"
EnableDependentAnimation="true"
Storyboard.TargetName="rec2"
Storyboard.TargetProperty="Width"
To="{Binding awayPercentage, Converter={StaticResource statswidthConverter}}" />
</Storyboard>
</Page.Resources>
<StackPanel
Padding="50"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Loaded="Grid_Loaded">
<Grid
Grid.Row="1"
Height="50"
BorderThickness="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition x:Name="clo1" Width="Auto" />
<ColumnDefinition Width="3" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<TextBlock
x:Name="tbl1"
HorizontalAlignment="Center"
Text="{Binding homePercentage}"
TextWrapping="Wrap" />
<Rectangle
x:Name="rec1"
Grid.Column="1"
Width="0"
Fill="#FF1DEE00"
Stroke="White"
StrokeThickness="0">
<Interactivity:Interaction.Behaviors>
<Interactions:DataTriggerBehavior
Binding="{Binding homePercentage}"
ComparisonCondition="GreaterThan"
Value="0">
<Media:ControlStoryboardAction Storyboard="{StaticResource Increase}" />
</Interactions:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Rectangle>
<Rectangle
Grid.Column="2"
Fill="White"
Stroke="White"
StrokeThickness="0" />
<Rectangle
x:Name="rec2"
Grid.Column="3"
Width="200"
Fill="#FF139D00"
Stroke="White"
StrokeThickness="0" >
<Interactivity:Interaction.Behaviors>
<Interactions:DataTriggerBehavior
Binding="{Binding awayPercentage}"
ComparisonCondition="LessThan"
Value="200">
<Media:ControlStoryboardAction Storyboard="{StaticResource decrease}" />
</Interactions:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Rectangle>
<TextBlock
x:Name="tbr1"
Grid.Column="4"
HorizontalAlignment="Center"
Text="{Binding awayPercentage}"
TextWrapping="Wrap" />
</Grid>
</StackPanel>
</Page>
Code behind
public sealed partial class MainPage : Page
{
ObservableCollection<Percentage> percentages;
public MainPage()
{
this.InitializeComponent();
percentages = new ObservableCollection<Percentage>()
{
new Percentage {homePercentage=63,awayPercentage=37 }
};
this.DataContext = percentages[0];
}
}
public class Percentage
{
public double homePercentage { get; set; }
public double awayPercentage { get; set; }
}
public class statswidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return (double)value * 2;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return (double)value / 2;
}
}
If you still want to set animation for ColumnDefinition.Width please use ObjectAnimationUsingKeyFrames which don't have so smoothly effects as DoubleAnimation the demo showed. To be smoothly need quite a lot frames. For example:
<Storyboard x:Name="storyobejct">
<ObjectAnimationUsingKeyFrames
Duration="0:0:3"
Storyboard.TargetName="clo1"
Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0" Value="1" />
<DiscreteObjectKeyFrame KeyTime="0:0:1" Value="50" />
<DiscreteObjectKeyFrame KeyTime="0:0:1.5" Value="60" />
<DiscreteObjectKeyFrame KeyTime="0:0:2.0" Value="100" />
<DiscreteObjectKeyFrame KeyTime="0:0:3" Value="126" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
Using which animation and which trigger depend on your layout and requirements. Pay attention that animating the Width seems to be a dependent animation which is not recommended. More details animation please reference Animations overview, more details about XAML behavior please reference this document.

UWP CommandBar with multiple overflow menus like Word Mobile?

I have a basic C# UWP app running on the desktop. The app's layout is similar to Word Mobile, i.e. it has a main menu with a command bar below to apply various commands.
The default CommandBar has primary commands (displayed as icons) and secondary commands shown in the overflow menu.
The Word Mobile app uses a special command bar with "groups" of command buttons. Each group has their own overflow menu should the window size be too small to show all commands (see screenshots below).
Is there a way to get these "grouped" commands with their own overflow menu using standard XAML controls? If not, what would be a strategy to implement a custom control like this?
Example:
(1) Wide window: CommandBar shows all command buttons:
(2) Small window: two separate overflow menu buttons:
Sorry about the delay but I thought I would post a proof of concept answer.
For this example I have created 7 action AppBarButton in a CommandBar including the following
2 Buttons that are independent - AllAppsButton, CalculatorButton
2 Buttons that are part of the CameraGroup - CameraButton, AttachCameraButton
3 Buttons that are part of the FontGroup - BoldButton, FontButton, ItalicButton
The idea is that if the screen size is less than 501 pixels I use VisualStateManager and AdaptiveTriggers to show the Group Chevron Buttons instead of the action Buttons. The action Buttons are then shown by clicking the down chevron which opens up a relevant Popup control.
The Popups are hidden again using AdaptiveTriggers if the screen is increased to 501 pixels or above.
MainPage.xaml
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CameraGroupStates">
<VisualState x:Name="Default">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="501" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="CameraButton.Visibility" Value="Visible"/>
<Setter Target="AttachCameraButton.Visibility" Value="Visible" />
<Setter Target="CameraGroupButton.Visibility" Value="Collapsed" />
<Setter Target="CameraGroupPopup.IsOpen" Value="false" />
<Setter Target="FontButton.Visibility" Value="Visible"/>
<Setter Target="BoldButton.Visibility" Value="Visible" />
<Setter Target="ItalicButton.Visibility" Value="Visible" />
<Setter Target="FontGroupButton.Visibility" Value="Collapsed" />
<Setter Target="FontGroupPopup.IsOpen" Value="false" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Minimal">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="CameraButton.Visibility" Value="Collapsed"/>
<Setter Target="AttachCameraButton.Visibility" Value="Collapsed" />
<Setter Target="CameraGroupButton.Visibility" Value="Visible" />
<Setter Target="FontButton.Visibility" Value="Collapsed"/>
<Setter Target="BoldButton.Visibility" Value="Collapsed" />
<Setter Target="ItalicButton.Visibility" Value="Collapsed" />
<Setter Target="FontGroupButton.Visibility" Value="Visible" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<CommandBar x:Name="MainCommandBar" Height="50">
<AppBarButton x:Name="AllAppsButton" Icon="AllApps"></AppBarButton>
<AppBarButton x:Name="CameraButton" Icon="Camera"></AppBarButton>
<AppBarButton x:Name="AttachCameraButton" Icon="AttachCamera"></AppBarButton>
<!--This is the Group Chevron button for Camera-->
<AppBarButton x:Name="CameraGroupButton" Visibility="Collapsed" Content=""
Click="CameraGroupButton_Click">
<AppBarButton.ContentTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Content}"
FontFamily="Segoe MDL2 Assets" HorizontalAlignment="Center"></TextBlock>
</Grid>
</DataTemplate>
</AppBarButton.ContentTemplate>
</AppBarButton>
<AppBarButton x:Name="CaluclatorButton" Icon="Calculator"></AppBarButton>
<AppBarButton x:Name="BoldButton" Icon="Bold"></AppBarButton>
<AppBarButton x:Name="FontButton" Icon="Font"></AppBarButton>
<AppBarButton x:Name="ItalicButton" Icon="Italic"></AppBarButton>
<!--This is the Group Chevron button for Fonts-->
<AppBarButton x:Name="FontGroupButton" Visibility="Collapsed" Content=""
Click="FontGroupButton_Click">
<AppBarButton.ContentTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Content}"
FontFamily="Segoe MDL2 Assets" HorizontalAlignment="Center"></TextBlock>
</Grid>
</DataTemplate>
</AppBarButton.ContentTemplate>
</AppBarButton>
</CommandBar>
<Popup x:Name="CameraGroupPopup" HorizontalAlignment="Right" HorizontalOffset="-120"
VerticalOffset="50" IsOpen="False">
<StackPanel Orientation="Horizontal" Width="120" Height="60" Background="LightGray"
HorizontalAlignment="Center">
<AppBarButton x:Name="CameraGroupCameraButton" Icon="Camera" Width="50" Height="50"
Foreground="Black"/>
<AppBarButton x:Name="CameraGroupAttachCameraButton" Icon="AttachCamera"
Foreground="Black" Width="50" Height="50"></AppBarButton>
</StackPanel>
</Popup>
<Popup x:Name="FontGroupPopup" HorizontalAlignment="Right" HorizontalOffset="-170"
VerticalOffset="50" IsOpen="False">
<StackPanel Orientation="Horizontal" Width="170" Height="60" Background="LightGray"
HorizontalAlignment="Center">
<AppBarButton x:Name="FontGroupBoldButton" Icon="Bold" Width="50" Height="50"
Foreground="Black"/>
<AppBarButton x:Name="FontGroupFontButton" Icon="Font"
Foreground="Black" Width="50" Height="50"></AppBarButton>
<AppBarButton x:Name="FontGroupItalicButton" Icon="Italic"
Foreground="Black" Width="50" Height="50"></AppBarButton>
</StackPanel>
</Popup>
</Grid>
Code behind contains 2 fields and 2 events used to hide/show relevant Popups, change chevrons to up/down arrow.
public sealed partial class MainPage : Page
{
public bool CameraGroupIsOpen { get; set; } = false;
public bool FontGroupIsOpen { get; set; } = false;
public MainPage()
{
this.InitializeComponent();
}
private void CameraGroupButton_Click(object sender, RoutedEventArgs e)
{
if (CameraGroupIsOpen)
{
CameraGroupPopup.IsOpen = false;
CameraGroupButton.Content = "\uE019";
CameraGroupIsOpen = false;
}
else
{
CameraGroupPopup.IsOpen = true;
CameraGroupButton.Content = "\uE018";
CameraGroupIsOpen = true;
}
}
private void FontGroupButton_Click(object sender, RoutedEventArgs e)
{
if (FontGroupIsOpen)
{
FontGroupPopup.IsOpen = false;
FontGroupButton.Content = "\uE019";
FontGroupIsOpen = false;
}
else
{
FontGroupPopup.IsOpen = true;
FontGroupButton.Content = "\uE018";
FontGroupIsOpen = true;
}
}
}
Quite a bit of code that could no doubt be vastly improved as a CustomControl but wanted to show the idea. Hope it helps
It's probably not super complicated, but it can be a lot of work nevertheless. It probably derives from the the ribbon where there are multiple groups with item collapse and drop priorities (I think) and items get dropped in priority order.
You would need to have a container panel that would read priorities from the groups included in it and in MeasureOverride - it would drive collapsing items in the groups when space pressure happens.
The ToolStrip control in my toolkit has code to move items between the toolstrip and the overflow dropdown (check sample here) and could be a good first step of implementing support for ribbon-like collapsing.
IIRC the official sample for CommandBar also has logic implemented to move items between PrimaryCommands and SecondaryCommands which you could look into.

Why won't Grid rows with height Auto resize with scale-transformed content?

Given the following code, I would have expected the red and green boxes to end up next to eachother, but as you can see in the screenshot of the result, they do not. Instead, the grid rows are sized to accommodate their full size, even though there is a render transform that scales them to half their height.
Is there a way to make the grid rows actually resize themselves and adjust to their contents?
I want this because I couldn't animate the heights of the rows, so I want to animate the heights of their contents instead.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Height="300"
Grid.Row="0"
Background="Red">
<Border.RenderTransform>
<ScaleTransform ScaleY="0.5" />
</Border.RenderTransform>
</Border>
<Border Height="200"
Grid.Row="1"
Background="Green">
<Border.RenderTransform>
<ScaleTransform ScaleY=".5" />
</Border.RenderTransform>
</Border>
</Grid>
As Sheridan says, a RenderTransform is just moving stuff around - independent of other elements. The neat thing is that it's fully hardware accelerated.
To have the system perform animations AND affect layout is a bit more tricky. You probably want to aim for not doing a pure resize, but instead use render transforms to have one element move on top of another, hence hiding it.
But, if you really do want a true resize of content, here's a way to do it.
First, I've added a row with height * at the bottom to allow your Auto rows to just use the size they need.
Secondly, I've created an animation (using Blend of course :) ) - and named the key frames in it, to be able to access them from code behind.
Lastly I modify the animation in the .cs file, and run the animation - voila! Note, this will not be hardware accelerated, but should work for simple UIs.
Code can also be found at: https://github.com/andyhammar/Wp81ResizeRowsTestApp
.xaml
<Page.Resources>
<Storyboard x:Name="AnimateRed">
<DoubleAnimationUsingKeyFrames EnableDependentAnimation="True" Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="_redBorder">
<EasingDoubleKeyFrame KeyTime="0" x:Name="redAnimationFromKeyFrame" Value="300"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" x:Name="redAnimationToKeyFrame" Value="200">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border
x:Name="_redBorder"
Height="300"
Grid.Row="0"
Background="Red">
</Border>
<Border
x:Name="_greenBorder"
Height="200"
Grid.Row="1"
Background="Green">
</Border>
<StackPanel
Grid.Row="2"
VerticalAlignment="Bottom"
HorizontalAlignment="Center"
Orientation="Horizontal">
<Button
x:Name="redSmallButton"
Content="red small"
Click="RedSmallButton_OnClick"/>
<Button
x:Name="redLargeButton"
Content="red large"
Click="RedLargeButton_OnClick"/>
</StackPanel>
</Grid>
.xaml.cs
private void RedSmallButton_OnClick(object sender, RoutedEventArgs e)
{
redAnimationFromKeyFrame.Value = 300;
redAnimationToKeyFrame.Value = 200;
AnimateRed.Begin();
}
private void RedLargeButton_OnClick(object sender, RoutedEventArgs e)
{
redAnimationFromKeyFrame.Value = 200;
redAnimationToKeyFrame.Value = 300;
AnimateRed.Begin();
}
They do, but I'd suggest that you use the LayoutTransform Property instead. The difference is that LayoutTransform is performed before the Arrange and Measure methods are called, so the new size is taken into consideration and RenderTransform is performed afterwards, so it ignores any dimension changes.
You can find a full explanation of the differences in the LayoutTransform vs. RenderTransform - What's the Difference? page on the Scott Logic website.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Height="300"
Grid.Row="0"
Background="Red">
<Border.LayoutTransform>
<ScaleTransform ScaleY="0.5" />
</Border.LayoutTransform>
</Border>
<Border Height="200"
Grid.Row="1"
Background="Green">
<Border.LayoutTransform>
<ScaleTransform ScaleY=".5" />
</Border.LayoutTransform>
</Border>
</Grid>

Fieldset in Winrt/XAML

I need to create something in WinRT/XAML similar to an HTML fielset. http://jsfiddle.net/Sf2Vy/
Basically, I have a border and there is some text on top of the border. Where the text covers the border, I need the border to not show under the text. The background behind the border isn't a solid color so I can't just set the background color of the text. The text length is variable also.
Is there an easy way to do this?
Yeah, so, the answer is no. There is no FieldSet.
Having said that, I think you could work out a similar effect simple enough. The code below shows you a solution that could easily be wrapped in a custom user control called fieldset.
<Grid Width="500" VerticalAlignment="Center">
<!-- top fieldset thing -->
<Grid VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="35" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="Border">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="BorderThickness" Value="0,5,0,0" />
<Setter Property="BorderBrush" Value="white" />
<Setter Property="Margin" Value="0,-2,0,0" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10,-15,10,0" />
<Setter Property="FontSize" Value="30" />
</Style>
</Grid.Resources>
<Border Grid.Column="0" />
<TextBlock Grid.Column="1" Text="User Info" />
<Border Grid.Column="2" />
</Grid>
<!-- regular form fields -->
<Border BorderBrush="White" BorderThickness="5,0,5,5">
<StackPanel Margin="20">
<TextBox Header="Salutation" />
<TextBox Header="First Name" />
<TextBox Header="Middle Name" />
<TextBox Header="Last Name" />
<Button Margin="0,5,-3,0" HorizontalAlignment="Right">Save Data</Button>
</StackPanel>
</Border>
</Grid>
It looks something like this:
It's not 100% perfect - or, maybe... it is.
Best of luck!