I'm looking for a solution to my WPF project.
I've an User Control with 2 different widget inside.
The first one animates the second with this function and the animation works fine:
private void expandTable(UIElement expandleft)
{
DoubleAnimation da = new DoubleAnimation(0, 700, TimeSpan.FromSeconds(0.5));
da.AutoReverse = false;
expandleft.BeginAnimation(Button.WidthProperty, da);
}
The point is: this user control is into a StackPanel on another page and what I want to do is animate the width of this StackPanel with the same animation.
But the above animation doesn't work as I want because the width of my StackPanel has to change according to the Width of the UserControl which in turn depends on the animation of the first Widget.
My answer is: how can I do something like that?:
private void expandStack(UIElement expand)
{
DoubleAnimation db = new DoubleAnimation(0, **auto**, TimeSpan.FromSeconds(0.5));
db.AutoReverse = false;
expan.BeginAnimation(StackPAnel.WidthProperty, db);
}
Hope I was clear.
Thanks to everyone!
Related
I'm developing a Windows Form application with WPF User Control embedded in the WF. If I add a button and execute my userControl.DrawWireFrameCube(); My ViewPort3D get updated. I'm using Helix 3D Toolkit. But If I call my method from my MainWindowForm class it doesn't get executed and UI is not updated,but only userControl.DrawWireFrameCube(); isn't working. The other userControl.Draw3DObject(insertionPoint, points, color); method is working fine.
private void VisualizePart(int index)
{
InsertionPoint insertionPoint = new InsertionPoint
{
X = _duplicatedListParts[index].INFO1,
Y = _duplicatedListParts[index].INFO2,
Z = _duplicatedListParts[index].INFO3
};
DetailSize points = new DetailSize
{
Length = _duplicatedListParts[index].LENGTH,
Width = _duplicatedListParts[index].WIDTH,
Thickness = _duplicatedListParts[index].THICKNESS
};
userControl.Dispatcher.Invoke(() =>
{
System.Windows.Media.Color color = System.Windows.Media.Color.FromRgb(255, 90, 0);
userControl.Draw3DObject(insertionPoint, points, color);
userControl.DrawWireFrameCube();
});
}
The difference is that in my Draw3DObject() I add items to Model3DGroup and in DrawWireFrameCube() I add items to MyViewPort3D. I'm not using XAML and I want to stay that way.
Any ideas what is wrong here?
P.S I love negative vote without explanation :)
I simply have an Image, and I set its width and height by assigning some numbers. For example, First Height and Width: 400 x 800. Second Height and Width: 200 x 400.
So if you do such a mainstreamed thing, there won't be any transition when resizing it, it just gets smaller immediately in a blink of eye. But I want it to resize between those "specific" measurements by transition (or animating) in 1 or 2 seconds.
I know Microsoft Expression Blend do some storyboards, but I could not do this by data binding. I databinded this image with a value, when the value changes, image resizes also. But I could not record any storyboard to create a transition.
What do you suggest me to do?
Thanks
I think something along the lines of this might work...
private void buttonStart_Click(object sender, RoutedEventArgs e)
{
CreateAnimation(400, 200).Begin();
}
private Storyboard CreateAnimation(double from, double to)
{
Storyboard sb = new Storyboard();
DoubleAnimation Animation = new DoubleAnimation();
Animation.From = from;
Animation.To = to;
Animation.Duration = new Duration(TimeSpan.FromSeconds(1.0));
Storyboard.SetTarget(Animation, ITEMNAME);
Storyboard.SetTargetProperty(Animation, new PropertyPath("(Width)"));
sb.Children.Add(Animation);
return sb;
}
Just create two double animations for the height and width to use simultaneously.
I have a Grid with a Adorner to provide some drawn pattern. See img: http://imgur.com/D649W
My problem is that this Adorner(dots on the Grid) is layered on top of everything. The white square are draggable but now when the Adorner are on top, I can't drag. I would like the layer to be behind every component added to the Grid. Any suggestions on how I can set the ZIndex?
Thanks.
Code below:
MyAdorner ad = new MyAdorner(grid);
AdornerLayer adLayer = AdornerLayer.GetAdornerLayer(grid);
adLayer.Add(ad);
I push my Button and this is adding the MyAdorner to the grid. MyAdorner looks like this:
public MyAdorner(Grid adornedGrid)
: base(adornedGrid) {
Height = adornedGrid.Height;
Width = adornedGrid.Width;
brush = new VisualBrush();
brush.Stretch = Stretch.Fill;
brush.TileMode = TileMode.Tile;
brush.Viewport = new Rect(0, 0, SnapDistance, SnapDistance);
brush.ViewportUnits = BrushMappingMode.Absolute;
brush.Viewbox = new Rect(0, 0, SnapDistance, SnapDistance);
brush.ViewboxUnits = BrushMappingMode.Absolute;
ellipse = new Ellipse() { Fill = new SolidColorBrush(Colors.Blue), Width = 2, Height = 2 };
brush.Visual = ellipse;
}
protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) {
Pen renderPen = new Pen(new SolidColorBrush(Colors.Black), 0);
drawingContext.DrawRectangle(brush, renderPen, new Rect(new Point(0, 0), AdornedElement.DesiredSize));
}
If your problem is that the adorner is covering the elements you want to manipulate so that they become un-draggable etc, set .IsHitTestVisible = False on the adorner.
You can also set the adorner's opacity to some semi-transparent value to see the background through it if that is desirable.
Is this what you're looking for?
Panel.SetZIndex(ad, 20)
Attached properties of the framework are usually asignable from static methods of the UIElement that holds it.
EDIT:
Possible alternative: - make your own Panel
Easy and dirty way to make sure that your wanted elements are ALWAYS on top:
Declare a static in a Util library:
public static int ZIndexCount;
Then when you want an element on top you simply do:
SetZIndex(_viewbox, Util.ZIndexCount++);
Of course, if your application runs 5 years without being interrupted the ZIndexCount will go back to 0...
It works like a charm in my applications.
I know this is quite old but I thought I try anyway:
You can add a new AdornerDecorator to you visual tree hierarchy to render the controls at the right level. By default the root of the tree provides the AdornerDecorator but you can add as many as you want and your the components you add will be rendered in them. For more information - see here
<Grid>
<AdornerDecorator>
...your Adorners render here
</AdornerDecorator>
</Grid>
https://wangmo.wordpress.com/2008/10/19/relations-between-adorner-adornerlayer-and-adornerdecorator/
In the example below, the border has a text block and a button inside. after the button is pressed, the fadeBorder is called and the border and everything in it fades nicely. If I try to call someMethod a 2nd time, the border opacity is still 0, and I can't see my border/message/button. I tried to set it back to one by doing myBorder.Opacity=1; This does not have any effect on the opacity, it's still set to 0 after this line. Is there a trick to resetting my Border opacity back to 1.0 after a storyboard has completed? I also tried setting a double var to 1.0, then assign that var to the border opacity, that did not have an effect either.
public void someMethod(string message) {
myTextBlock.Text = message;
myStackPanel.Children.Add(myTextBlock);
Ect... with Button Control and alignment of controls
fadeBorder();
protected void fadeBorder() {
var fade = new DoubleAnimation() {
From = 1,
To = 0,
Duration = TimeSpan.FromSeconds(this.secondsToFade),
};
Storyboard.SetTarget(fade, myBorder);
Storyboard.SetTargetProperty(fade, new PropertyPath(Border.OpacityProperty));
storyBoard.Children.Add(fade);
storyBoard.Begin();
}
How to: Set a Property After Animating It with a Storyboard
I'm learning WPF and have a specific goal.
Imagine you have a grid (3 rows by 3 columns), and a control, say a simple blue rectangle fills the middle cell. When I click on the cell I want the square to rotate smoothly through 180 degrees.
The specific issue I have at the moment is; as the rectangle rotates, it won't change its dimensions, so it will extend beyond the boundary of the cell. I don't want it to clip, i want it to appear on top, partially obscuring surrounding cells.
The second part of this is, if there is one cell that fills the entire window, and I click on the blue rectangle in that cell, can I make the rectangle rotate and extend beyond the sides of the form?
If that doesn't make sense, please ask. I'm finding it hard to google because I don't know the exact terms I should be using.
Thank you
The first part can be acomplished by using the attached property Panel.ZIndex, set it to a high value when you start the animation and a lower value when the animation is complete. The second part (having a control outside of the window) is more complicated. I tried a few things and this method seemed to be the best. It uses a full screen window instead of a Popup as I encountered cliping issues. A copy of the element is made using RenderTargetBitmap this is then placed in the same position. The original element is hidden whilst the copy is animated.
public void PopupAnimation(UIElement element)
{
double w = element.RenderSize.Width,h = element.RenderSize.Height;
var screen = new Canvas();
var pos = element.PointToScreen(new Point(0, 0));
var rtb = new RenderTargetBitmap((int)w,(int)h, 96, 96, PixelFormats.Pbgra32);
rtb.Render(element);
Image i = new Image { Source = rtb, Width = w, Height = h,Stretch=Stretch.Fill};
Canvas.SetLeft(i, pos.X);
Canvas.SetTop(i, pos.Y);
screen.Children.Add(i);
var window = new Window() {
Content = screen, AllowsTransparency = true,
Width=SystemParameters.PrimaryScreenWidth,Height=SystemParameters.PrimaryScreenHeight,
WindowStyle=WindowStyle.None,ShowInTaskbar=false,Topmost=true,
Background=Brushes.Transparent,ShowActivated=false,Left=0,Top=0
};
var transform = new RotateTransform();
i.RenderTransformOrigin = new Point(0.5, 0.5);
i.RenderTransform = transform;
var anim = new DoubleAnimation { To = 360 };
anim.Completed += (s,e) =>
{
element.Visibility = Visibility.Visible;
var delay = new Storyboard { Duration = TimeSpan.FromSeconds(0.1) };
delay.Completed += (s2, e2) => window.Close();
delay.Begin();
};
window.ContentRendered += (s, e) =>
{
transform.BeginAnimation(RotateTransform.AngleProperty, anim);
element.Visibility = Visibility.Hidden;
};
window.Show();
}