Storyboard.SetTarget vs Storyboard.SetTargetName - c#

Why does Storyboard.SetTargetName works but Storyboard.SetTarget does not?
Here xaml -
<Grid Grid.Row="0" ClipToBounds="True">
<X:SmartContentControl x:Name="smartContent" Content="{Binding Path=MainContent}" ContentChanging="smartContent_ContentChanging">
<X:SmartContentControl.RenderTransform>
<TranslateTransform x:Name="translateTransformNew" X="0" Y="0"/>
</X:SmartContentControl.RenderTransform>
</X:SmartContentControl>
<ContentControl Content="{Binding ElementName=smartContent, Path=LastImage}">
<ContentControl.RenderTransform>
<TranslateTransform x:Name="translateTransformLast" X="0" Y="0"/>
</ContentControl.RenderTransform>
</ContentControl>
</Grid>
Here C#
private void smartContent_ContentChanging(object sender, RoutedEventArgs e)
{
Storyboard storyBoard = new Storyboard();
DoubleAnimation doubleAnimation1 = new DoubleAnimation(0.0, -smartContent.RenderSize.Width, new Duration(new TimeSpan(0, 0, 0, 0, 500)));
DoubleAnimation doubleAnimation2 = new DoubleAnimation(smartContent.RenderSize.Width, 0.0, new Duration(new TimeSpan(0, 0, 0, 0, 500)));
doubleAnimation1.AccelerationRatio = 0.5;
doubleAnimation2.DecelerationRatio = 0.5;
storyBoard.Children.Add(doubleAnimation1);
storyBoard.Children.Add(doubleAnimation2);
Storyboard.SetTarget(doubleAnimation1, this.translateTransformLast); //--- this does not work
//Storyboard.SetTargetName(doubleAnimation1, "translateTransformLast"); -- this works
Storyboard.SetTargetProperty(doubleAnimation1, new PropertyPath(TranslateTransform.XProperty));
Storyboard.SetTarget(doubleAnimation2, this.translateTransformNew);//--- this does not work
//Storyboard.SetTargetName(doubleAnimation2, "translateTransformNew"); -- this works
Storyboard.SetTargetProperty(doubleAnimation2, new PropertyPath(TranslateTransform.XProperty));
if (smartContent.LastImage != null)
storyBoard.Begin();
}

I found answer here!
Why don't these animations work when I'm using a storyboard?
Storyboard cant animate TranslateTransform, since it is not UIElement.
This is how i do it now! :)
Storyboard.SetTarget(doubleAnimation1, this.lastImage);
Storyboard.SetTargetProperty(doubleAnimation1, new PropertyPath("RenderTransform.(TranslateTransform.X)"));
Storyboard.SetTarget(doubleAnimation2, this.smartContent);
Storyboard.SetTargetProperty(doubleAnimation2, new PropertyPath("RenderTransform.(TranslateTransform.X)"));

Related

Animating the translation of a programmatically created xaml object

Initially I did it directly on nInput and everything worked.
Then I tried to move it to a cloned object (cloneInputForAnimation) but I get this error:
System.InvalidOperationException: The name 'TextBoxAnim' could not be
found in the namespace of 'System.Windows.Controls.TextBox'
XAML:
<TextBox x:Name="nInput" MaxLength="17" PreviewTextInput="numberValidationTextBox" Grid.Column="0"
Height="80" Width="240"
Foreground="White" Background="#202020"
HorizontalAlignment="Left" BorderThickness="0"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
FontSize="25">
<TextBox.RenderTransform>
<TranslateTransform x:Name="TextBoxAnim" />
</TextBox.RenderTransform>
<TextBox.Resources>
<Storyboard x:Key="myStoryboardY" x:Name="myStoryboardY">
<DoubleAnimation
Storyboard.TargetName="TextBoxAnim"
x:Name="myDoubleAnimationY"
Storyboard.TargetProperty="Y"
Duration="0:0:0.8"
/>
</Storyboard>
<Storyboard x:Key="myStoryboardX" x:Name="myStoryboardX">
<DoubleAnimation
Storyboard.TargetName="TextBoxAnim"
x:Name="myDoubleAnimationX"
Storyboard.TargetProperty="X"
Duration="0:0:0.8"
/>
</Storyboard>
<Storyboard x:Key="myStoryboardWidth" x:Name="myStoryboardWidth">
<DoubleAnimation
Storyboard.TargetName="nInput"
x:Name="myDoubleAnimationWidth"
Storyboard.TargetProperty="(TextBox.Width)"
Duration="0:0:0.8"
/>
</Storyboard>
<Storyboard x:Key="myStoryboardHeight" x:Name="myStoryboardHeight">
<DoubleAnimation
Storyboard.TargetName="nInput"
x:Name="myDoubleAnimationHeight"
Storyboard.TargetProperty="(TextBox.Height)"
Duration="0:0:0.8"
/>
</Storyboard>
</TextBox.Resources>
</TextBox>
C#:
//I clone the input box to perform the animation
TextBox cloneInputForAnimation = CloneXaml(nInput);
UserInteraction.Children.Add(cloneInputForAnimation);
//Removing text from the realInput
nInput.Text = "";
//nInput.IsEnabled = false;
//Creating a new object which is the one that will remain after the animation
TextBox targetInput = CloneXaml(cloneInputForAnimation);
targetInput.Visibility = Visibility.Hidden;
targetInput.Width = Double.NaN;
targetInput.Height = 50;
nList.Children.Add(targetInput);
//Obtaining the destination point
Point targetPosition = targetInput.TransformToAncestor(rootView).Transform(new Point(0, 0));
//Obtaining the current point
Point currentPos = cloneInputForAnimation.TransformToAncestor(rootView).Transform(new Point(0, 0));
//Calculating the translation to do to reach targetPosition
Vector translateToDo = targetPosition - currentPos;
//Obtaining storyboard and anim for x, y, width, height of cloneInputForAnimation (I can't use x:Name because is an element created programmatically)
Storyboard myStoryY = cloneInputForAnimation.Resources["myStoryboardY"] as Storyboard;
Storyboard myStoryX = cloneInputForAnimation.Resources["myStoryboardX"] as Storyboard;
Storyboard myStoryHeight = cloneInputForAnimation.Resources["myStoryboardHeight"] as Storyboard;
Storyboard myStoryWidth = cloneInputForAnimation.Resources["myStoryboardWidth"] as Storyboard;
DoubleAnimation myAnimY = myStoryY.Children[0] as DoubleAnimation;
DoubleAnimation myAnimX = myStoryX.Children[0] as DoubleAnimation;
DoubleAnimation myAnimHeight = myStoryHeight.Children[0] as DoubleAnimation;
DoubleAnimation myAnimWidth = myStoryWidth.Children[0] as DoubleAnimation;
myAnimY.To = translateToDo.Y;
myAnimX.To = translateToDo.X;
myAnimHeight.To = targetInput.ActualHeight;
myAnimWidth.To = targetInput.ActualWidth;
cloneInputForAnimation.BeginStoryboard(myStoryY);
cloneInputForAnimation.BeginStoryboard(myStoryX);
cloneInputForAnimation.BeginStoryboard(myStoryHeight);
cloneInputForAnimation.BeginStoryboard(myStoryWidth);
C# CloneXaml:
public static T CloneXaml<T>(T source)
{
string xaml = XamlWriter.Save(source);
StringReader sr = new StringReader(xaml);
XmlReader xr = XmlReader.Create(sr);
return (T)XamlReader.Load(xr);
}
Sorry but these are my first steps with WPF so the code will probably have a lot of problems.
Okay, as I imagined I was using a completely wrong approach.
This is the working version I have arrived at.
XAML:
<TextBox x:Name="nInput" MaxLength="17" PreviewTextInput="numberValidationTextBox" Grid.Column="0"
Height="80" Width="240"
Foreground="White" Background="#202020"
HorizontalAlignment="Left" BorderThickness="0"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
FontSize="25">
<TextBox.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="12" />
</Style>
</TextBox.Resources>
</TextBox>
C#:
Duration animDuration = new Duration(new TimeSpan(0, 0 ,0, 0,800));
//I clone the input box to perform the animation
TextBox cloneInputForAnimation = CloneXaml(nInput);
UserInteraction.Children.Add(cloneInputForAnimation);
//Removing text from the realInput
nInput.Text = "";
//nInput.IsEnabled = false;
//Creating a new object wich is the one that will remain after the animation
TextBox targetInput = CloneXaml(cloneInputForAnimation);
targetInput.Visibility = Visibility.Hidden;
targetInput.Width = double.NaN;
targetInput.Height = 50;
nList.Children.Add(targetInput);
//Obtaining the destination point
Point targetPosition = targetInput.TransformToAncestor(rootView).Transform(new Point(0, 0));
//Obtaining the current point
Point currentPos = cloneInputForAnimation.TransformToAncestor(rootView).Transform(new Point(0, 0));
//Calculating the translation to do to reach targetPosition
Vector translateToDo = targetPosition - currentPos;
TranslateTransform myTranslateTransform = new TranslateTransform();
cloneInputForAnimation.RenderTransform = myTranslateTransform;
DoubleAnimation myAnimX = new DoubleAnimation {
Duration = animDuration,
To = translateToDo.X
};
DoubleAnimation myAnimY = new DoubleAnimation {
Duration = animDuration,
To = translateToDo.Y
};
DoubleAnimation myAnimHeight = new DoubleAnimation {
Duration = animDuration,
To = 50,
};
DoubleAnimation myAnimWidth = new DoubleAnimation {
Duration = animDuration,
To = 50,
};
myTranslateTransform.BeginAnimation(TranslateTransform.YProperty, myAnimY);
myTranslateTransform.BeginAnimation(TranslateTransform.XProperty, myAnimX);
cloneInputForAnimation.BeginAnimation(TextBox.WidthProperty, myAnimWidth);
cloneInputForAnimation.BeginAnimation(TextBox.HeightProperty, myAnimHeight);
C# CloneXaml has not been modified

How to change ImageBrush dynamically?

Here is some code that does not work:
XAML:
<TextBox />
<TextBox.Background>
<ImageBrush x:Name="image_background" Stretch="Fill" TileMode="None" AlignmentX="Left" AlignmentY="Center" />
</TextBox.Background>
</TextBox>
C#: (It does not work to dynamically change image.)
image_background.ImageSource = null;
image_background.ImageSource = CreateBitmapSource(System.Windows.Media.Color.FromArgb(255, 0, 0, 0)); // Black Color
Is not changing the image, any solution?
Here is code that works fine.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// work fine
image_background.ImageSource = CreateBitmapSource(System.Windows.Media.Color.FromArgb(255, 0, 255, 0));
}
UPDATE:
System.Windows.Application.Current.Dispatcher.Invoke(
DispatcherPriority.Background,
new Action(() => image_background.ImageSource = CreateBitmapSource(System.Windows.Media.Color.FromArgb(255, 0, 255, 0))));

ColorAnimation change color in rectangle

I want change rectange color, but, color doesn't change. Where is problem?
ColorAnimation col = new ColorAnimation();
col.From = Colors.Aqua;
col.To = Colors.PaleGreen;
col.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard zgo = new Storyboard();
Storyboard.SetTarget(col, c);
Storyboard.SetTargetProperty(col,
new PropertyPath(SolidColorBrush.ColorProperty));
zgo.Children.Add(col);
zgo.Begin();
And here is XAML:
<Rectangle Name="rec"
Height="100" Width="200"
HorizontalAlignment="Left" VerticalAlignment="Top"
Stroke="Black"
MouseLeftButtonDown="rec_MouseLeftButtonDown">
<Rectangle.Fill>
<SolidColorBrush x:Name="c"></SolidColorBrush>
</Rectangle.Fill>
</Rectangle>
Run the animation directly by calling Animatable.BeginAnimation:
var colorAnimation = new ColorAnimation(
Colors.Aqua, Colors.PaleGreen, TimeSpan.FromSeconds(1));
c.BeginAnimation(SolidColorBrush.ColorProperty, colorAnimation);
You could still do it with a Storyboard by using the Rectangle as the animation's target and Fill.Color as target property::
Storyboard storyboard = new Storyboard();
Storyboard.SetTarget(colorAnimation, rec);
Storyboard.SetTargetProperty(colorAnimation, new PropertyPath("Fill.Color"));
storyboard.Children.Add(colorAnimation);
storyboard.Begin();

Displaying Image in Circle in Windows Phone

I am creating a WP (7.1+8) app, that requires me to display images inside a circle ( as in Google+ ).
I found a solution that uses a GradientBrush to accomplish the task via following code:-
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.UriSource = new Uri("http://url-of-the-image", UriKind.Absolute);
image.CacheMode = new BitmapCache();
image.Source = bitmapImage;
image.Stretch = Stretch.UniformToFill;
image.VerticalAlignment = System.Windows.VerticalAlignment.Center;
//Setting up the mask
RadialGradientBrush opacityMask = new RadialGradientBrush();
GradientStop gs1 = new GradientStop();
GradientStop gs2 = new GradientStop();
GradientStop gs3 = new GradientStop();
gs1.Color = Color.FromArgb(255, 0, 0, 0);
gs1.Offset = 0.0;
gs2.Color = Color.FromArgb(255, 0, 0, 0);
gs2.Offset = 0.999;
gs3.Color = Color.FromArgb(0, 0, 0, 0);
gs3.Offset = 1.0;
opacityMask.GradientStops.Add(gs1);
opacityMask.GradientStops.Add(gs2);
opacityMask.GradientStops.Add(gs3);
image.OpacityMask = opacityMask;
I want to know that what will be the performance impact if i needed to do this on large number of images, say 50.
Use clipping to display partial area of a control.
<Image Source="YouImage.jpg">
<Image.Clip>
<EllipseGeometry Center="50,50" RadiusX="50" RadiusY="50" />
</Image.Clip>
</Image>
Change the Center, RadiusX and RadiusY to your convenience.
Use the following code snippet for your requirement.
<Ellipse Height="300" Width="300">
<Ellipse.Fill>
<ImageBrush ImageSource="images/WmDev.jpg" AlignmentX="Center" AlignmentY="Center" />
</Ellipse.Fill>
</Ellipse>
Hope it Helps.
This question is already answered still if you want to see it in more detail then you could have a look here
The XAML solution will be,
<Image Source=”{Binding Converter={StaticResource ContactPictureConverter}}” Width=”48″ Height=”48″ Stretch=”Fill”
>
<Image.Clip>
<EllipseGeometry Center=”24,24″ RadiusX=”24″ RadiusY=”24″ />
</Image.Clip>
</Image>

LinearGradientBrush animation

I am trying to convert "wipe" animation http://learnwpf.com/post/2006/10/03/How-can-I-create-a-e2809cwipee2809d-effect-to-transition-between-two-images-in-WPF.aspx sample to use it in C#.
So I did like:
<Grid>
<Image Source="C:\Temp\WMS\Others\megan_fox_17-normal.jpg" />
<Image Source="C:\Temp\WMS\Others\Hudgens.jpg">
<Image.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="Black" x:Name="BlackStop"/>
<GradientStop Offset="0" Color="Transparent" x:Name="TransparentStop"/>
</LinearGradientBrush>
</Image.OpacityMask>
</Image>
<Button Content="Button" HorizontalAlignment="Left" Margin="72,288,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
</Grid>
and
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var _doubleAnimationFrontPlayer = new DoubleAnimation();
_doubleAnimationFrontPlayer.By = 1;
_doubleAnimationFrontPlayer.Duration = new Duration(TimeSpan.FromSeconds(2));
sb.Children.Add(_doubleAnimationFrontPlayer);
Storyboard.SetTargetProperty(_doubleAnimationFrontPlayer, new PropertyPath(GradientStop.OffsetProperty));
Storyboard.SetTargetName(TransparentStop, "TransparentStop");
Storyboard.SetTarget(_doubleAnimationFrontPlayer, TransparentStop);
var _doubleAnimationFrontPlayer2 = new DoubleAnimation();
_doubleAnimationFrontPlayer2.By = 1;
_doubleAnimationFrontPlayer2.Duration = new Duration(TimeSpan.FromSeconds(2));
_doubleAnimationFrontPlayer2.BeginTime = TimeSpan.FromMilliseconds(1000) ;
sb.Children.Add(_doubleAnimationFrontPlayer2);
Storyboard.SetTargetProperty(_doubleAnimationFrontPlayer2, new PropertyPath(GradientStop.OffsetProperty));
Storyboard.SetTargetName(BlackStop, "BlackStop");
Storyboard.SetTarget(_doubleAnimationFrontPlayer2, BlackStop);
sb.Completed += sb_Completed;
sb.Begin();
}
void sb_Completed(object sender, EventArgs e)
{
Debug.WriteLine("DONE");
}
But nothing happens... :(
Any clue what is missing?
THANK YOU!
P.S. I found too late the same question here WPF Translating an XAML Animation to C# Code
So th ecorrect code I found here WPF Translating an XAML Animation to C# Code
I just edited it because I found 3 errors there:
public void WipeAnimation(FrameworkElement ObjectToAnimate)
{
LinearGradientBrush OpacityBrush = new LinearGradientBrush();
OpacityBrush.StartPoint = new Point(1, 0);
OpacityBrush.EndPoint = new Point(0, 0);
GradientStop BlackStop = new GradientStop(Colors.Black, 0);
GradientStop TransparentStop = new GradientStop(Colors.Transparent, 0);
OpacityBrush.GradientStops.Add(BlackStop);
OpacityBrush.GradientStops.Add(TransparentStop);
ObjectToAnimate.OpacityMask = OpacityBrush;
this.RegisterName("TransparentStop", TransparentStop);
this.RegisterName("BlackStop", BlackStop);
Duration d = TimeSpan.FromSeconds(4);
Storyboard sb = new Storyboard() { Duration = d };
DoubleAnimation DA = new DoubleAnimation() { By = 1, Duration = d };
DoubleAnimation DA2 = new DoubleAnimation() { By = 1, Duration = d };
sb.Children.Add(DA); sb.Children.Add(DA2);
Storyboard.SetTargetName(DA, "TransparentStop");
Storyboard.SetTargetName(DA2, "BlackStop");
Storyboard.SetTargetProperty(DA, new PropertyPath("Offset"));
Storyboard.SetTargetProperty(DA2, new PropertyPath("Offset"));
sb.Begin(this);
}
Author got +1 as well! :)

Categories

Resources