I have a password box and under it i have a rectangle. I want the rectangle to expand from 0 to 200 width when the password box gets focus.
this is the XAML code
<Rectangle x:Name="passwordbox_underline" Grid.Row="2"
Grid.Column="1" Fill="YellowGreen" RadiusX="1" RadiusY="1" Width="0" HorizontalAlignment="Left"/>
<PasswordBox Grid.Column="1"
Grid.Row="1"
Style="{StaticResource hi}" CaretBrush="White" FontStretch="Expanded" x:Name="pass" GotFocus="pass_GotFocus"/>
And this is the C# code:
private void pass_GotFocus(object sender, RoutedEventArgs e)
{
Duration duration = new Duration(TimeSpan.FromSeconds(2));
DoubleAnimation myDoubleAnimation1 = new DoubleAnimation();
myDoubleAnimation1.Duration = duration;
Storyboard sb = new Storyboard();
sb.Duration = duration;
Storyboard.SetTarget(myDoubleAnimation1, passwordbox_underline);
Storyboard.SetTargetProperty(myDoubleAnimation1, new PropertyPath("Rectangle.Width"));
myDoubleAnimation1.From = 0;
myDoubleAnimation1.To = 200;
sb.Begin();
}
But it doesn't work and nothing happens. Where's the problem?
I got it working. There we a couple minor issues.
First, you never added your DoubleAnimation to your Storyboard. You need the following
sb.Children.Add(myDoubleAnimation1);
Next, your property path is a bit off. You're working on the Rectangle, so you don't specify it as part of the path. It is just be "Width".
Storyboard.SetTargetProperty(myDoubleAnimation1, new PropertyPath("Width"));
Last, your rectangle had no height so it still was not visible when animated. I added a height of 5 for testing.
<Rectangle x:Name="passwordbox_underline" Grid.Row="2"
Grid.Column="1" Fill="YellowGreen" RadiusX="1" RadiusY="1" Width="0" Height="5" HorizontalAlignment="Left"/>
Putting it all together, this code snippet will animate (but don't forget to add a height to your rectangle):
Duration duration = new Duration(TimeSpan.FromSeconds(2));
DoubleAnimation myDoubleAnimation1 = new DoubleAnimation();
myDoubleAnimation1.Duration = duration;
Storyboard sb = new Storyboard();
sb.Duration = duration;
Storyboard.SetTarget(myDoubleAnimation1, passwordbox_underline);
Storyboard.SetTargetProperty(myDoubleAnimation1, new PropertyPath("Width"));
myDoubleAnimation1.From = 0;
myDoubleAnimation1.To = 200;
sb.Children.Add(myDoubleAnimation1);
sb.Begin();
Related
I have a WPF Canvas with a TextBlock and an Image on it. The text is animated, but it doesn't look smooth. I tried many combinations of different FPS-Settings and durations but it won't get better.
I also want to let the text fade-in/out at the start and ending. But I found no methods to do so.
At the moment it looks like that:
How can I get the animation smoothly? How can I fade it in/out smoothly?
Before you ask, I need to show the Window invisible because I use the WpfAppBar and that component needs an HWND.
Here is the canvas xaml:
<Canvas x:Name="canMain" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<Border x:Name="boLogo" Panel.ZIndex="2" Height="40" Background="Gray" Canvas.Left="0" Canvas.Top="-20">
<Image Height="39" Width="auto" Margin="5, 0, 5, 0" Source="pack://siteoforigin:,,,/Resources/Logo.png" />
</Border>
<TextBlock x:Name="tbInfo" Panel.ZIndex="1" Visibility="Hidden" RenderOptions.BitmapScalingMode="NearestNeighbor" FontSize="32" TextOptions.TextFormattingMode="Display" TextOptions.TextRenderingMode="ClearType" FontFamily="Arial" FontWeight="Bold" Padding="5" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform x:Name="AnimatedTranslateTransform" X="0" Y="0" />
</TextBlock.RenderTransform>
</TextBlock>
</Canvas>
And the code to animate the text:
public void ShowWindow(Brush fontColor, Brush backgroundColor, string str) {
var helper = new WindowInteropHelper(this);
helper.EnsureHandle();
tbInfo.Foreground = fontColor;
this.Background = backgroundColor;
tbInfo.Text = str;
this.Height = 39;
this.Width = SystemParameters.WorkArea.Width;
this.Left = SystemParameters.PrimaryScreenWidth - this.Width;
ShowWindowInvisible();
WpfAppBar.AppBarFunctions.SetAppBar(this, WpfAppBar.ABEdge.Top);
Visibility = Visibility.Visible;
int duration = 10 + str.Length / 5;
TextMarquee(duration);
}
private void TextMarquee(int duration)
{
Timeline.DesiredFrameRateProperty.OverrideMetadata(
typeof(Timeline),
new FrameworkPropertyMetadata { DefaultValue = 60 }
);
double height = canMain.ActualHeight - tbInfo.ActualHeight;
tbInfo.Margin = new Thickness(0, height / 2, 0, 0);
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = canMain.ActualWidth;
doubleAnimation.To = tbInfo.ActualWidth *-1;
doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(duration));
tbInfo.BeginAnimation(Canvas.LeftProperty, doubleAnimation);
tbInfo.Visibility = Visibility.Visible;
}
private void ShowWindowInvisible()
{
var width = Width;
var height = Height;
var windowStyle = WindowStyle;
var showInTaskbar = ShowInTaskbar;
var showActivated = ShowActivated;
Width = 0;
Height = 0;
WindowStyle = WindowStyle.None;
ShowInTaskbar = false;
ShowActivated = false;
Show();
Visibility = Visibility.Hidden;
Width = width;
Height = height;
WindowStyle = windowStyle;
ShowInTaskbar = showInTaskbar;
ShowActivated = showActivated;
}
I have wired Manipulation events with the listviewitem to capture left swipe and right swipe. But when I try to scroll down the listview, it does not work! The manipulation events get fired and the listview does not scroll!
This is the listview Datatemplate
<Grid Height="60" Width="380" Margin="0,0,0,1">
<Grid x:Name="ItemGrid" HorizontalAlignment="Left" VerticalAlignment="Center" Width="380" Height="60" Background="Orange" Canvas.ZIndex="2"
ManipulationMode="TranslateX" ManipulationStarted="On_ChannelItem_ManipulationStarted" ManipulationDelta="On_ChannelItem_ManipulationDelta" ManipulationCompleted="OnChannelItemManipulationCompleted">
<TextBlock x:Name="titleTextBlock" Margin="20,0,0,0" Canvas.ZIndex="2" VerticalAlignment="Center" TextAlignment="Left" FontSize="25" >
</TextBlock>
</Grid>
<Grid x:Name="DelGrid" Opacity="0.0" HorizontalAlignment="Right" VerticalAlignment="Center" Height="60" Background="Red" Canvas.ZIndex="-1" Tapped="On_ChannelDelete_Tap" Width="380">
<Button Content="X" FontSize="25" Canvas.ZIndex="-1" VerticalAlignment="Center" HorizontalAlignment="Center" Width="380" BorderThickness="0" />
</Grid>
</Grid>
This is the manipulation events
private void OnChannelItemManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
Grid ChannelGrid = (Grid)sender;
Grid DeleteGrid = (Grid)((Grid)(ChannelGrid.Parent)).Children[1];
double dist = e.Cumulative.Translation.X;
if (dist < -100) // Swipe left
{
Storyboard SwipeLeft = new Storyboard();
DoubleAnimation OpacityAnimation = new DoubleAnimation();
OpacityAnimation.EnableDependentAnimation = true;
OpacityAnimation.From = 0.0;
OpacityAnimation.To = 1.0;
OpacityAnimation.BeginTime = TimeSpan.FromMilliseconds(0);
OpacityAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(1));
Storyboard.SetTarget(OpacityAnimation, DeleteGrid);
Storyboard.SetTargetProperty(OpacityAnimation, "Opacity");
SwipeLeft.Children.Add(OpacityAnimation);
DoubleAnimation WidthAnimation = new DoubleAnimation();
WidthAnimation.EnableDependentAnimation = true;
WidthAnimation.From = 380;
WidthAnimation.To = 0;
WidthAnimation.BeginTime = TimeSpan.FromMilliseconds(30);
WidthAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(100));
Storyboard.SetTarget(WidthAnimation, ChannelGrid);
Storyboard.SetTargetProperty(WidthAnimation, "Width");
SwipeLeft.Children.Add(WidthAnimation);
SwipeLeft.Begin();
}
else if (dist > 100) // Swipe right
{
Storyboard SwipeRight = new Storyboard();
ColorAnimation changeColorAnimation = new ColorAnimation();
changeColorAnimation.EnableDependentAnimation = true;
changeColorAnimation.To = Colors.Green;
changeColorAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(100));
Storyboard.SetTarget(changeColorAnimation, ChannelGrid);
PropertyPath p = new PropertyPath("(ChannelGrid.Background).(SolidColorBrush.Color)");
Storyboard.SetTargetProperty(changeColorAnimation, p.Path);
SwipeRight.Children.Add(changeColorAnimation);
SwipeRight.Begin();
}
}
How do I enable the normal listview scrolling as well as the swipe? Vertical Scrolling is possible when I remove the manipulation events
Update your manipulation mode to include System:
ManipulationMode="TranslateX,System"
I have a canvas that has a double animation implemented after it is transformed closer to a specific co-ordinates.
The transform and double animation works fine. But after the animation is complete, the canvas resets into right most corner of the layout. Weird thing is, this behavior does not exist if I do not give any width to the canvas or remove the grid columns.
Any ideas what am I missing here? I am trying to have source on the right of the page and target on the left.
EDIT -1:
After some testing I realized that the values are not resetting, but the storyboard/double animation itself is moving the canvas far right. I do not understand what is causing this though.
EDIT-2:
On further investigation, looks like double animation always starts with initial co-ordinates of the canvas rather than using the current location. Even when from co-ordinates are mentioned relative to whole grid, it only animates based on original layout. Is there a way Force the storyboard to use current location?
Here is the code:
XAML:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<Canvas Name="target" >
<Rectangle Width="150" Height="150" Fill="Gray" />
</Canvas>
<Canvas Name="source" ManipulationMode="All" Grid.Column="1">
<Rectangle Name="testRectangle" Width="150" Height="150" Fill="Blue" />
</Canvas>
</Grid>
Code Behind:
Public Point p = new Point(225, 225);
public MainPage()
{
this.InitializeComponent();
DragabbleRectangle();
}
private void DragabbleRectangle()
{
source.ManipulationDelta += source_ManipulationDelta;
source.RenderTransform = new CompositeTransform(); ;
}
void source_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
Point origin = new Point(0, 0);
Canvas rect = sender as Canvas;
Point pT= rect.TransformToVisual(Window.Current.Content).TransformPoint(origin);
CompositeTransform tT = rect.RenderTransform as CompositeTransform;
tT.TranslateX += e.Delta.Translation.X;
tT.TranslateY += e.Delta.Translation.Y;
var distance = Math.Pow(pT.X - p.X,2) + Math.Pow(pT.Y-p.Y, 2);
if (distance < 2500)
{
Duration d = TimeSpan.FromSeconds(1);
rect.Margin = new Thickness(0);
rect.RenderTransform = tT;// new CompositeTransform();
DoubleAnimation xAnimation = new DoubleAnimation { To = p.X, From = pT.X,
Duration = d, EasingFunction = new QuinticEase() };
DoubleAnimation yAnimation = new DoubleAnimation { To = p.Y, From = pT.Y,
Duration = d, EasingFunction = new QuinticEase() };
Storyboard.SetTargetProperty(xAnimation, "(UIElement.RenderTransform).(CompositeTransform.TranslateX)");
Storyboard.SetTargetProperty(yAnimation, "(UIElement.RenderTransform).(CompositeTransform.TranslateY)");
Storyboard storyboard = new Storyboard();
Storyboard.SetTarget(storyboard, rect);
storyboard.Children.Add(xAnimation);
storyboard.Children.Add(yAnimation);
storyboard.Begin();
}
}
Looks like you are not subscribing to the story board completed event. If this is the case you will have to give the relative distance from the original coordinates. Here is something you can try that should do the trick:
name the root grid as layout
<Grid x:name="layout" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
...
...
</Grid>
in the code behind change the animations to relative distance...
Point relative = layout.TransformToVisual(source).TransformPoint(origin);
DoubleAnimation xAnimation = new DoubleAnimation { To = p.X + relative.X, From = tT.TranslateX,
Duration = d, EasingFunction = new QuinticEase() };
DoubleAnimation yAnimation = new DoubleAnimation { To = p.Y + relative.Y, From = tT.TranslateY,
Duration = d, EasingFunction = new QuinticEase() };
I want to change the scale of Rectangle using storyboard, I don't know why it doesn't work. Looking forward to anyone's reply! The C# code is:
Storyboard sb = new Storyboard();
InitializeComponent();
DoubleAnimation daScaleX = new DoubleAnimation();
daScaleX.From = 1;
daScaleX.To = 2;
daScaleX.Duration = TimeSpan.FromSeconds(3);
DoubleAnimation daScaleY = new DoubleAnimation();
daScaleY.From = 1;
daScaleY.To = 2;
daScaleY.Duration = TimeSpan.FromSeconds(3);
BounceEase easing = new BounceEase()
{
EasingMode = EasingMode.EaseOut
};
daScaleX.EasingFunction = easing;
daScaleY.EasingFunction = easing;
Storyboard.SetTargetProperty(daScaleX, new PropertyPath("ScaleX"));
Storyboard.SetTarget(daScaleX, st);
Storyboard.SetTargetProperty(daScaleY, new PropertyPath("ScaleY"));
Storyboard.SetTarget(daScaleY, st);
sb.Children.Add(daScaleX);
sb.Children.Add(daScaleY);
sb.Begin();
The XAML file is:
<Grid>
<StackPanel>
<Rectangle x:Name="rect" Fill="Blue" Width="200" Height="40" Margin="5" RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="st" ScaleX="1" ScaleY="1" />
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
</Grid>
Try this below code separately..it works for me
<Grid>
<StackPanel>
<Rectangle x:Name="rect" Fill="Blue" Width="200" Height="40" Margin="5" RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<ScaleTransform x:Name="st" ScaleX="1.0" ScaleY="1.0"></ScaleTransform>
</Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
</Grid>
and did this animation on windows loaded event
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Storyboard sb = new Storyboard();
DoubleAnimation daScaleX = new DoubleAnimation();
daScaleX.From = 1;
daScaleX.To = 2;
daScaleX.Duration = TimeSpan.FromMilliseconds(300);
DoubleAnimation daScaleY = new DoubleAnimation();
daScaleY.From = 1;
daScaleY.To = 2;
daScaleY.Duration = TimeSpan.FromMilliseconds(300);
BounceEase easing = new BounceEase()
{
EasingMode = EasingMode.EaseOut
};
daScaleX.EasingFunction = easing;
daScaleY.EasingFunction = easing;
Storyboard.SetTargetProperty(daScaleX, new PropertyPath("RenderTransform.ScaleX"));
Storyboard.SetTarget(daScaleX, rect);
Storyboard.SetTargetProperty(daScaleY, new PropertyPath("RenderTransform.ScaleY"));
Storyboard.SetTarget(daScaleY, rect);
sb.Children.Add(daScaleX);
sb.Children.Add(daScaleY);
sb.Begin();
}
I have a Grid which scaled/zoomed with ScaleTransform by slider. At runtime many UIElements are added to this Grid.
I want to show some tooltips, but not scaled! How should I do that?
For the example: Grid has scaleX and scaleY 2, so I set new ScaleTransform(0.5, 0.5), but didn't help. It seems that the most similar value is 0.740.. Why?
Even Grid's LayoutTransform.Inverse is set to scale values 0.5.
XAML:
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Height="Auto" Width="Auto" Name="graphScrollViewer" ScrollChanged="graphScrollViewer_ScrollChanged">
<Grid Margin="0,0,0,0" Name="graphGrid" Width="Auto" Height="Auto" ScrollViewer.IsDeferredScrollingEnabled="True" MouseLeftButtonDown="graphGrid_MouseLeftButtonDown" MouseLeftButtonUp="graphGrid_MouseLeftButtonUp" MouseMove="graphGrid_MouseMove">
<Grid.LayoutTransform>
<ScaleTransform ScaleX="{Binding ElementName=sldZoom, Path=Value}" ScaleY="{Binding ElementName=sldZoom, Path=Value}" />
</Grid.LayoutTransform>
</Grid>
</ScrollViewer>
<Slider Minimum="0.1" Maximum="20" Value="1" x:Name="sldZoom" Panel.ZIndex="10" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,20,20" Height="23" Width="100" ValueChanged="sldZoom_ValueChanged"/>
Code-behind:
(method of Rectangle (MouseEnter event) dynamically added to grid)
private void rect_MouseEnter(object sender, MouseEventArgs e)
{
RectToolTip = new TextBlock();
RectToolTip.HorizontalAlignment = HorizontalAlignment.Left;
RectToolTip.VerticalAlignment = VerticalAlignment.Top;
RectToolTip.TextAlignment = TextAlignment.Center;
RectToolTip.Height = this.HeaderTwoHeight + 1;
RectToolTip.Text = " " + (RectsTasks[(sender as Rectangle)]).Info + " ";
RectToolTip.Background = this.ToolTipBackground;
RectToolTip.Foreground = this.ToolTipFontColor;
RectToolTipBorder = new Border();
RectToolTipBorder.Child = RectToolTip;
RectToolTipBorder.BorderThickness = new Thickness(this.ToolTipBorderThickness);
RectToolTipBorder.BorderBrush = this.ToolTipBorderColor;
RectToolTipBorder.Margin = new Thickness(e.GetPosition((graphGrid)).X + 10, e.GetPosition((graphGrid)).Y + 10, 0, 0);
RectToolTipBorder.VerticalAlignment = System.Windows.VerticalAlignment.Top;
RectToolTipBorder.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
graphGrid.Children.Add(RectToolTipBorder);
RectToolTipBorder.LayoutTransform = RectToolTip.LayoutTransform = new ScaleTransform(????);
Grid.SetZIndex(RectToolTip, 20);
Grid.SetZIndex(RectToolTipBorder, 20);
}
You need to assign the inverse transform to the child element, so that the child will stay intact.
RectToolTipBorder.LayoutTransform = graphGrid.LayoutTransform.Inverse as Transform;