My Code is like this.
I want to create Grid dynamically.
creation is success, but I can't animate it's color.
What is my mistake?
Grid[] grid = new Grid[99];
for (int i = 0; i < 10; i++) {
grid[i] = new Grid();
grid[i].Width = grid[i].Height = 100;
grid[i].Background = Brushes.WhiteSmoke;
Storyboard sb = new Storyboard();
ColorAnimation ca = new ColorAnimation(Colors.DarkTurquoise, TimeSpan.FromMilliseconds(250));
Storyboard.SetTarget(ca, grid[i]);
Storyboard.SetTargetProperty(ca, new PropertyPath("Fill.Color"));
sb.Children.Add(ca);
grid[i].MouseEnter += delegate(object sender2, MouseEventArgs e2) {
sb.Begin(this);
};
stackMain.Children.Add(grid[i]);
}
WPF Grid has no Fill property you will have to use Background
Storyboard.SetTargetProperty(ca, new PropertyPath("Background.Color"));
In addition to what sa_ddam has said, you would also have to create a Brush, since the built-in brushes (like Brushes.WhiteSmoke in your example) can't be animated.
grid[i].Background = new SolidColorBrush(Colors.WhiteSmoke);
...
Storyboard.SetTargetProperty(ca, new PropertyPath("Background.Color"));
It might also save some code if you omit the Storyboard and run the animation directly:
var brush = new SolidColorBrush(Colors.WhiteSmoke);
grid[i].Background = brush;
var ca = new ColorAnimation(Colors.DarkTurquoise, TimeSpan.FromMilliseconds(250));
grid[i].MouseEnter +=
(o, e) => brush.BeginAnimation(SolidColorBrush.ColorProperty, ca);
Related
I am having trouble adding multiple effects within an animation sequence in WPF. I have multiple rectangles arranged within a grid and the way the animation effect is to work is in the following order:
By default, the user sees the grid such that every cell is bounded by a silver border on a black canvas, the color of the rectangle within each cell could be transparent/black.
On mouse hover, the rectangle in the cell changes its stroke and fill to green.
On exiting the mouse over, the previous cell slowly changes color to its default state before the mouse hover.
I was able to do the animation effect for just the stroke color but not combine it with the fill properties. Here is the code snippet for creating the rectangles within the grid:
Style cellStyle = PrepareAnimationStyle();
foreach (string label in rowHeaders)
{
for (int n = 0; n < numOfCols; n++)
grid.Children.Add(new Rectangle()
{
Stroke = Brushes.Silver,
StrokeThickness = 2,
Fill = Brushes.Transparent,
Height = cellSize,
Width = cellSize,
Style = cellstyle
});
}
And here is the code that sets the animation (still in progress, can't make it work as required):
Style PrepareAnimationStyle()
{
Trigger animTrigger = new Trigger();
animTrigger.Property = ContentElement.IsMouseOverProperty;
animTrigger.Value = true;
System.Windows.Media.Animation.ColorAnimation toGreen = new System.Windows.Media.Animation.ColorAnimation((Color)ColorConverter.ConvertFromString("#FF66CC00"), TimeSpan.FromSeconds(0));
toGreen.FillBehavior = FillBehavior.HoldEnd;
System.Windows.Media.Animation.ColorAnimation toTransparent = new System.Windows.Media.Animation.ColorAnimation(Colors.Transparent, TimeSpan.FromSeconds(1));
System.Windows.Media.Animation.ColorAnimation toSilver = new System.Windows.Media.Animation.ColorAnimation(Colors.Silver, TimeSpan.FromSeconds(1));
System.Windows.Media.Animation.Storyboard sbEnter = new System.Windows.Media.Animation.Storyboard();
//Storyboard.SetTargetProperty(toGreen, new PropertyPath("Stroke.Color"));
Storyboard.SetTargetProperty(toGreen, new PropertyPath("(Shape.Fill).(SolidColorBrush.Color)"));
sbEnter.Children.Add(toGreen);
/*Storyboard sbFill = new Storyboard();
Storyboard.SetTargetProperty(toGreen, new PropertyPath("Fill.Color"));
sbFill.Children.Add(toSilver);
Storyboard sbFillEmpty = new Storyboard();
Storyboard.SetTargetProperty(toTransparent, new PropertyPath("Fill.Color"));
sbFillEmpty.Children.Add(toSilver);*/
Storyboard sbExit = new Storyboard();
//Storyboard.SetTargetProperty(toSilver, new PropertyPath("Stroke.Color"));
Storyboard.SetTargetProperty(toTransparent, new PropertyPath("Fill.Color"));
sbExit.Children.Add(toSilver);
animTrigger.EnterActions.Add(new BeginStoryboard() { Storyboard = sbEnter });
//animTrigger.EnterActions.Add(new BeginStoryboard() { Storyboard = sbFill });
//animTrigger.EnterActions.Add(new BeginStoryboard() { Storyboard = sbFillEmpty });
animTrigger.ExitActions.Add(new BeginStoryboard() { Storyboard = sbExit });
Style cellStyle = new Style();
cellStyle.Triggers.Add(animTrigger);
return cellStyle;
}
Here you go
Style PrepareAnimationStyle()
{
Trigger animTrigger = new Trigger();
animTrigger.Property = FrameworkElement.IsMouseOverProperty;
animTrigger.Value = true;
ColorAnimation strokeToGreen = new ColorAnimation((Color)ColorConverter.ConvertFromString("#FF66CC00"), TimeSpan.FromSeconds(0));
ColorAnimation strokeToSilver = new ColorAnimation(Colors.Silver, TimeSpan.FromSeconds(1));
ColorAnimation fillToGreen = new ColorAnimation((Color)ColorConverter.ConvertFromString("#FF66CC00"), TimeSpan.FromSeconds(0));
ColorAnimation fillToTransparent = new ColorAnimation(Colors.Transparent, TimeSpan.FromSeconds(1));
Storyboard sbEnter = new Storyboard();
Storyboard.SetTargetProperty(strokeToGreen, new PropertyPath("Stroke.Color"));
Storyboard.SetTargetProperty(fillToGreen, new PropertyPath("Fill.Color"));
sbEnter.Children.Add(strokeToGreen);
sbEnter.Children.Add(fillToGreen);
Storyboard sbExit = new Storyboard();
Storyboard.SetTargetProperty(strokeToSilver, new PropertyPath("Stroke.Color"));
Storyboard.SetTargetProperty(fillToTransparent, new PropertyPath("Fill.Color"));
sbExit.Children.Add(strokeToSilver);
sbExit.Children.Add(fillToTransparent);
animTrigger.EnterActions.Add(new BeginStoryboard() { Storyboard = sbEnter });
animTrigger.ExitActions.Add(new BeginStoryboard() { Storyboard = sbExit });
Style cellStyle = new Style();
cellStyle.Triggers.Add(animTrigger);
return cellStyle;
}
in order to make it work properly make sure to set a fill and stroke while you add the cell
example
Style cellStyle = PrepareAnimationStyle(); //this line is out side of the cell loop
....
rect.Fill = new SolidColorBrush(Colors.Transparent);
rect.Stroke = new SolidColorBrush(Colors.Silver);
rect.Style = cellStyle;
I am working in silverlight and under a very strange situation that i need to implement my own SelectionChangedEventHandler handler function .The reason to do so is:
I have my situation like this :
private static Grid GenerateList(Parameter param, int LoopCount, Grid g)
{
Grid childGrid = new Grid();
ColumnDefinition colDef1 = new ColumnDefinition();
ColumnDefinition colDef2 = new ColumnDefinition();
ColumnDefinition colDef3 = new ColumnDefinition();
childGrid.ColumnDefinitions.Add(colDef1);
childGrid.ColumnDefinitions.Add(colDef2);
childGrid.ColumnDefinitions.Add(colDef3);
TextBlock txtblk1ShowStatus = new TextBlock();
TextBlock txtblkLabel = new TextBlock();
ListBox lines = new ListBox();
ScrollViewer scrollViewer = new ScrollViewer();
scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
lines.ItemsSource = param.Component.Attributes.Items;
scrollViewer.Content = lines;
Grid.SetColumn(scrollViewer, 1);
Grid.SetRow(scrollViewer, LoopCount);
childGrid.Children.Add(scrollViewer);
lines.SelectedIndex = 0;
lines.SelectedItem = param.Component.Attributes.Items;// This items contains 1000000,3 00000, and so on.
lines.SelectionChanged += new SelectionChangedEventHandler(List_SelectionChanged);
// lines.SelectionChanged += new SelectionChangedEventHandler(List_SelectionChanged(lines, txtblk1ShowStatus));
lines.SelectedIndex = lines.Items.Count - 1;
Grid.SetColumn(txtblk1ShowStatus, 2);
Grid.SetRow(txtblk1ShowStatus, LoopCount);
childGrid.Children.Add(txtblk1ShowStatus);
g.Children.Add(childGrid);
return (g);
}
static void List_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
MessageBox.Show("clist _SelectionChanged1");
//The problem is line below because i am "lines" and "txtblk1ShowStatus" are not in the
//scope of this function and i cannot declare them globally.
txtblk1ShowStatus.Text = lines[(sender as ListBox).SelectedIndex];
}
Here you can see that i have no access of of "lines" and "txtblk1ShowStatus" in the List_SelectionChanged(object sender, SelectionChangedEventArgs e) function. And i cannot declate the button and list globally because this function GenerateList(...) will be reused and it's just coded in c# (no xaml used).Please let me know how to do that and also explain how to do that if you have another way to do but please explain your code with detail
I think a lambda expression will help you solve your issues (you might need to edit it):
lines.SelectedIndex = 0;
lines.SelectedItem = param.Component.Attributes.Items;// This items contains 1000000,3 00000, and so on.
lines.SelectionChanged += (o,e) => {
MessageBox.Show("clist _SelectionChanged1");
txtblk1ShowStatus.Text = lines.SelectedItem.ToString();
};
lines.SelectedIndex = lines.Items.Count - 1;
i am trying to make a animation in which all the elements of my particular grid should vibrate.
so i tried this code ..
Storyboard hintstoryboard = new Storyboard();
for (int i = 3; i < gridpieces.Children.Count; i++)
{
DoubleAnimationUsingKeyFrames doubleanimation = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTargetName(doubleanimation, ((Image)gridpieces.Children[i]).Name);
Storyboard.SetTargetProperty(doubleanimation, "(UIElement.Projection).(PlaneProjection.RotationZ)");
EasingDoubleKeyFrame frame = new EasingDoubleKeyFrame();
frame.KeyTime = TimeSpan.FromSeconds(0.1);
frame.Value = -5;
EasingDoubleKeyFrame frame1 = new EasingDoubleKeyFrame();
frame1.KeyTime = TimeSpan.FromSeconds(0.2);
frame1.Value = 0;
EasingDoubleKeyFrame frame2 = new EasingDoubleKeyFrame();
frame2.KeyTime = TimeSpan.FromSeconds(0.3);
frame2.Value = 5;
EasingDoubleKeyFrame frame3 = new EasingDoubleKeyFrame();
frame3.KeyTime = TimeSpan.FromSeconds(0.4);
frame3.Value = 0;
doubleanimation.KeyFrames.Add(frame);
doubleanimation.KeyFrames.Add(frame1);
doubleanimation.KeyFrames.Add(frame2);
doubleanimation.KeyFrames.Add(frame3);
hintstoryboard.Children.Add(doubleanimation);
}
hintstoryboard.Begin();
but it is giving an exception that target name is not found but my grid have the image with same same name... i have made that grid by code only...
Any help will be appreciated.
I don't think you can use SetTargetName outside of XAML. In code behind you should replace this:
Storyboard.SetTargetName(doubleanimation, ((Image)gridpieces.Children[i]).Name);
with this
Storyboard.SetTarget(doubleanimation, (Image)gridpieces.Children[i]);
I saw an example on how to create a glow effect when the image gets focus in mark-up.
Below is the C# code example i found that uses double animation for opacity of a rectangle, i need to perform a glow or swivel effect using C# and not markup since i am not comfortable with it.
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 1.0;
myDoubleAnimation.To = 0.0;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));
myDoubleAnimation.AutoReverse = true;
myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.OpacityProperty));
You can add this in your Main(), after InitializeComponent();
textBlock1.Text = "Mouse over me";
var effect = new DropShadowEffect();
effect.Color = Colors.Red;
effect.BlurRadius = 10d;
effect.Opacity = 0d;
effect.ShadowDepth = 0d;
textBlock1.Effect = effect;
textBlock1.MouseEnter += (s, e) => {
var anim = new DoubleAnimation(0d, 1d, new Duration(TimeSpan.FromMilliseconds(500)));
effect.BeginAnimation(DropShadowEffect.OpacityProperty, anim); };
textBlock1.MouseLeave += (s, e) => {
var anim = new DoubleAnimation(1d, 0d, new Duration(TimeSpan.FromMilliseconds(500)));
effect.BeginAnimation(DropShadowEffect.OpacityProperty, anim); };
But I'd suggest stop wasting time with C# for GUI code, XAML is so much more convenient.
I am trying to get these ellipses to grow but I cannot figure out how to start the animation. This is my first attempt at WPF animation and I don't quite understand how it all works.
private void drawEllipseAnimation(double x, double y)
{
StackPanel myPanel = new StackPanel();
myPanel.Margin = new Thickness(10);
Ellipse e = new Ellipse();
e.Fill = Brushes.Yellow;
e.Stroke = Brushes.Black;
e.Height = 0;
e.Width = 0;
e.Opacity = .8;
canvas2.Children.Add(e);
Canvas.SetLeft(e, x);
Canvas.SetTop(e, y);
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 0;
myDoubleAnimation.To = 10;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));
myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
Storyboard.SetTargetName(myDoubleAnimation, e.Name);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Ellipse.HeightProperty));
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Ellipse.WidthProperty));
}
You don't need a Storyboard here. Just do
e.BeginAnimation(Ellipse.WidthProperty, myDoubleAnimation);
e.BeginAnimation(Ellipse.HeightProperty, myDoubleAnimation);
If you really need to do it with a Storyboard, you will have to add separate animations, one per animated property, to the Storyboard. And you have to call SetTarget instead of SetTargetName when you don't apply a name. Finally you'll need to start the Storyboard by calling Begin:
DoubleAnimation widthAnimation = new DoubleAnimation
{
From = 0,
To = 10,
Duration = TimeSpan.FromSeconds(5)
};
DoubleAnimation heightAnimation = new DoubleAnimation
{
From = 0,
To = 10,
Duration = TimeSpan.FromSeconds(5)
};
Storyboard.SetTargetProperty(widthAnimation, new PropertyPath(Ellipse.WidthProperty));
Storyboard.SetTarget(widthAnimation, e);
Storyboard.SetTargetProperty(heightAnimation, new PropertyPath(Ellipse.HeightProperty));
Storyboard.SetTarget(heightAnimation, e);
Storyboard s = new Storyboard();
s.Children.Add(widthAnimation);
s.Children.Add(heightAnimation);
s.Begin();