I'm looking for a sample wizard control for UWP. I am looking for a control that uses forward and backward buttons to transition from one panel to the next.
I have tried to implement my own by animating the width of panels in a horizontally oriented StackPanel, but it doesn't work as expected (the width is not animated and reverts back).
<Page.Resources>
<Storyboard x:Name="GoToNextAnimation" Storyboard.TargetName="LeftPanel">
<DoubleAnimation Storyboard.TargetProperty="Width" From="100" To="0" AutoReverse="False" Duration="0:0:1" />
</Storyboard>
</Page.Resources>
<StackPanel Orientation="Horizontal" Width="100" Tapped="StackPanel_Tapped" Background="Red" Height="50">
<Button x:Name="LeftPanel" Background="Yellow" Width="100" Height="50" />
<Button x:Name="RightPanel" Background="Green" Width="100" Height="50" />
</StackPanel>
with the event handler beginning the animation:
bool isLeft = true;
private void StackPanel_Tapped(object sender, TappedRoutedEventArgs e)
{
if (isLeft)
{
GoToNextAnimation.Begin();
}
else
{
LeftPanel.Width = 100;
}
isLeft = !isLeft;
}
When I tep the control it briefly (much quicker than the animation is intended to run for) changes to the red color (background of StackPanel) before reverting back to yellow (*never showing the green for the RightPanel).
Related
I tested both Word 2010 and Word 2019 on the same systems and same Keyboard Properties.
I did not change the properties of the Windows Keyboard.
Cursor movement and cursor blinking were fast in Word 2010, but very slow in Word 2019.
I want to modify Cursor's blink rate and movement speed in wpf project.
How to do it? Thanks for any help.
<Grid>
<TextBox x:Name="tb" Height="230" Padding="4" TextWrapping="Wrap" AcceptsReturn="True" Width="320" Focusable="True" Loaded="tb_Loaded" />
</Grid>
private void tb_Loaded(object sender, RoutedEventArgs e)
{
Keyboard.Focus(tb);
}
Edit:
I looked here but don't know if it is correct and how to do it.
WPF basically respects Windows's control panel settings of the blink rate. So does Word 2019 on my system. If you want to change the rate on your textbox, your only option is to disable the built-in caret (text cursor), and draw it yourself.
The following is shamelessly stolen inspired by this article, with some kinks ironed out:
SelectionChanged triggers too early when TextBox height is not a full multiple of line height causing buggy cursor positioning. Changed to LayoutUpdated.
Caret.Height respects the text height, instead of hardcoded.
Now on to the magic. Try this on your MainWindow.xaml:
<Grid x:Name="YouNeedAGridToContainTheTextBoxAndCanvas">
<TextBox x:Name="CustomTextBox"
FontSize="20"
AcceptsReturn="True" TextWrapping="Wrap"
CaretBrush="Transparent" />
<!--CaretBrush must be Transparent, as we will draw manually below-->
<Canvas ClipToBounds="True">
<Border x:Name="Caret"
Width="4"
Visibility="Collapsed"
Background="Transparent"> <!--Start drawing Transparent-->
<Border.Triggers>
<EventTrigger RoutedEvent="Border.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames
Storyboard.TargetProperty="Background.Color"
FillBehavior="HoldEnd">
<ColorAnimationUsingKeyFrames.KeyFrames>
<!--Ease to Red in 1sec-->
<EasingColorKeyFrame KeyTime="0:0:1.0" Value="Red"/>
<!--Ease back into Transparent in another 1sec-->
<EasingColorKeyFrame KeyTime="0:0:2.0" Value="Transparent" />
</ColorAnimationUsingKeyFrames.KeyFrames>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
</Border>
</Canvas>
</Grid>
You then need to manually update the drawing position by using code behind in your MainWindow.xaml.cs:
public MainWindow() //Constructor
{
InitializeComponent();
CustomTextBox.LayoutUpdated += (_, _) => {
var rect = CustomTextBox.GetRectFromCharacterIndex(CustomTextBox.CaretIndex);
if (rect.IsEmpty) return;
Canvas.SetLeft(Caret, rect.Left);
Canvas.SetTop(Caret, rect.Top);
Caret.Height = rect.Height;
};
CustomTextBox.LostFocus += (_, _) => Caret.Visibility = Visibility.Collapsed;
CustomTextBox.GotFocus += (_, _) => Caret.Visibility = Visibility.Visible;
CustomTextBox.Focus();
}
Feel free to tweak the color animation, adding frames as needed and playing with the KeyTime for faster/slower pulsing. Use <DiscreteColorKeyFrame> instead of <EasingColorKeyFrame> if you want a hard blink instead of pulsing.
This is for a WPF application. I have a label with some text. What I want is that when the mouse is hovered over the label, the color of the text will slowly change to another color. When the mouse is moved away, the color will slowly change back to its original color.
My code in MainWindow.xaml:
<Label
x:Name="mLabel"
Height="32.446"
Margin="18.339,65.5,0,0"
Padding="5,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="Hello"
FontSize="36"
FontWeight="Bold"
Foreground="#19418D"
MouseEnter="MLabel_MouseEnter"
MouseLeave="MLabel_MouseLeave"
MouseLeftButtonUp="MLabel_MouseLeftButtonUp"
RenderTransformOrigin="0.5,0.5"
Style="{StaticResource CustomFont}"
UseLayoutRounding="False">
<Label.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform Angle="360.086" />
<TranslateTransform />
</TransformGroup>
</Label.RenderTransform>
</Label>
My code in MainWindow.xaml.cs:
private void MLabel_MouseEnter(object sender, MouseEventArgs e)
{
mLabel.Foreground = (SolidColorBrush)(new BrushConverter().ConvertFrom("#7BA8FE"));
}
private void MLabel_MouseLeave(object sender, MouseEventArgs e)
{
mLabel.Foreground = (SolidColorBrush)(new BrushConverter().ConvertFrom("#19418D"));
}
Right now, it's an instant change from dark blue to light blue. But I want that change to happen slowly in a few seconds.
This question is different because I am working with foreground color of a label control here but the other solution is for background color of buttons which has a different way to implement.
Using this example Label Hover
Create a new project and just after your window Title
Title="MainWindow" Height="450" Width="800">
paste the following
<Window.Resources>
<Style x:Key="MyLabel">
<Style.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)">
<ColorAnimation To="#7BA8FE" Duration="0:0:0:2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)">
<ColorAnimation To="#19418D" Duration="0:0:0:2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
The drop any label on the screen from the toolbox and change it's style property to the following
<Label Content="Label" Style="{DynamicResource MyLabel}" HorizontalAlignment="Left" Margin="335,170,0,0" VerticalAlignment="Top" FontSize="20"/>
I am trying to create a pageFlip animation. Now on swipe gesture myStoryboard.Begin() is called.
The animation begins in code, but the screen doesn't show the animation happening. But if i switch away from the window and switch back (say 5 seconds after myStoryboard.Begin() was called then the animation is visible (from 5th second onwards) as though Storyboard was working as usual.
<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName= "RightPageImageOverlay"
Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)"
EnableDependentAnimation="True"
From="0" To="10" Duration="0:0:10" />
</Storyboard>
The Image :
<Grid Grid.Row="1" x:Name="flipViewGrid" >
<Canvas x:Name="flipViewCanvas" >
<WebView x:Name="flipViewWebView" NavigationCompleted="WebView_NavigationCompleted" Source="http://127.0.0.1:2121" Height="{Binding ElementName=flipViewCanvas, Path=ActualHeight}" Width="{Binding ElementName=flipViewCanvas, Path=ActualWidth}" Canvas.Left="0" Canvas.Top="0">
</WebView>
<StackPanel Orientation="Horizontal" Canvas.Left="0" Canvas.Top="0" Canvas.ZIndex="1">
<Image x:Name="LeftPageImageOverlay" Height="{Binding ElementName=flipViewCanvas, Path=ActualHeight}" Width="{Binding ElementName=flipViewCanvas, Path=ActualWidth }" Loaded="PageImageOverlay_Loaded" ></Image>
<Image x:Name="RightPageImageOverlay" Height="{Binding ElementName=flipViewCanvas, Path=ActualHeight}" Width="{Binding ElementName=flipViewCanvas, Path=ActualWidth }" Loaded="PageImageOverlay_Loaded" ManipulationMode ="All" ManipulationCompleted="RightPageImageOverlay_ManipulationCompleted" ManipulationDelta="RightPageImageOverlay_ManipulationDelta" >
<Image.Projection >
<PlaneProjection RotationY="0" CenterOfRotationX="0" x:Name="flipViewPlaneProjection"/>
</Image.Projection>
</Image>
</StackPanel>
</Canvas>
</Grid>
Update : I have expanded on the context of Image. How the code is supposed to work is as follows. When FlipViewWebView is loaded, 2 screenshots of the left and right half of the page are taken and laid over FlipViewWebView. When swipe gesture is detected, myStoryboard plays. Below is the code which triggers the page flip animation when I swipe.
private void RightPageImageOverlay_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (e.Velocities.Linear.X > .5 || e.Velocities.Linear.X < -.5) //say
if (myStoryboard.GetCurrentState() == Windows.UI.Xaml.Media.Animation.ClockState.Stopped)
myStoryboard.Begin();
Debug.WriteLine("Velocity : " + e.Velocities.Linear.X.ToString());
}
Update 2 :Another thing i noticed was that the flipping animation is visible if you swipe immediately after the page loads. But if you swipe say after a second or two, it is not visible.
I asked this on MSDN forums and they replied that there seems to be bugs involving PlaneProjection and that a report had been filed.
In the mean time, I have found a work-around. It seems the control being animated doesn't want to move away from 0 degrees.If you change the From value of DoubleAnimation to any value other than "0", say "0.01" it will work.
I have a wrappanel bound to an observablecolelction.
Is there a way to animate the movement of items in the UI when the collection is changed in the code behind? Kind of like the fluid movement of windows tiles style metro apps?
Any design ideas of how to go about this will be appreciated.
Right now, all I can think of is animating the layout chaging event?
Thanks
I've needed such thing in the past and -as I remember- I ended using a slightly modified version of the sample provided here:
https://learn.microsoft.com/en-us/archive/blogs/devdave/layout-transitions-an-animatable-wrappanel
This sample is somewhat advanced and supports animating the items when any modification is made to the collection (adding items, deleting items, resizing the panel)
On the other hand if what you need is a simple animation at the item level only (e.g. when an item is appearing/disappearing) it's much simpler you can build an ItemTemplate with a control that has an EventTrigger for the relevant event. This example will animate the item when added:
XAML:
<StackPanel>
<ItemsControl x:Name="itemsControl" Height="300">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="80" Height="80" Fill="Red" Margin="4" Opacity="0">
<Rectangle.RenderTransform>
<TranslateTransform Y="20" />
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="00:00:00.6" />
<DoubleAnimation Storyboard.TargetProperty="(RenderTransform).Y" To="0" Duration="00:00:00.4" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Width="60" Height="40" Content="Add Item" Click="Button_Click" />
</StackPanel>
Code behind:
ObservableCollection<string> items = new ObservableCollection<string>();
public MainWindow()
{
InitializeComponent();
itemsControl.ItemsSource = items;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
items.Add("New Item");
}
i want a silverlight listbox whose items are automatic scrollable (like a vertical marquee)
You might try using an ItemsControl setting the ItemsControl.ItemPanel to a StackPanel with a TranslateTransform applied on it. Then you can have a running Storyboard that adjusts the position of the Y coordinate of the Translate Transform.
EDIT: Example
<Border BorderBrush="Black" BorderThickness="2"
Height="100" Width="100"
HorizontalAlignment="Left" VerticalAlignment="Top" >
<Border.Clip>
<RectangleGeometry Rect="0,0,100,100" />
</Border.Clip>
<ItemsControl ItemsSource="{StaticResource Collection}">
<ItemsControl.RenderTransform>
<TranslateTransform x:Name="Transform" />
</ItemsControl.RenderTransform>
<i:Interaction.Triggers>
<i:EventTrigger>
<ei:ControlStoryboardAction
Storyboard="{StaticResource TransformMove}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ItemsControl>
</Border>
Then include this Storyboard in your control resources:
<Storyboard x:Key="TransformMove" Storyboard.TargetName="Transform" Storyboard.TargetProperty="Y">
<DoubleAnimation From="-100" To="100" Duration="0:0:10"
RepeatBehavior="Forever"/>
</Storyboard>