I have animation code in MainWindow for a cube which is GeometryModel3D object
Animation code
private void animate(GeometryModel3D back)
{
Transform3DGroup transGroup = new Transform3DGroup();
DoubleAnimation cardAnimation = new DoubleAnimation();
cardAnimation.From = 0;
cardAnimation.To = 0.3;
cardAnimation.Duration = new Duration(TimeSpan.FromSeconds(2));
cardAnimation.AutoReverse = true;
Transform3D transform = new TranslateTransform3D(0, 0, 0);
transGroup.Children.Add(transform);
back.Transform = transGroup;
transform.BeginAnimation(TranslateTransform3D.OffsetZProperty,
cardAnimation);
}
In Main window Code I have
Window1 win1 = new Window1();
public MainWindow()
{
InitializeComponent();
}
public void textbox_keydown( KeyEventArgs e)
{
if(e.Key==Key.Return)
{
if( some condition nothing to do with animation at all)
{
animate(cube);
win1.ShowDialogue();
}
//Position1
}
}
When i run program first time animation does not show and window1 show, now again i put some entry in textbox and enter again second time animation shows and after that every time only first time it does not show.
Also if i put "animate(cube);" at position 1 animation works even first time also and off course every other time too.
Why animation is not working first time when textbox_keydown( KeyEventArgs e) invoked in above case and working only second time and onwards when textbox_keydown( KeyEventArgs e) is invoked.
Is there any threadind problem or initiation i am forgetting ?
Above animation function is in MainWindow after textbox_keydown( KeyEventArgs e) .
Related
I try to move a grid in my window with an animation, but the animation doesn't happen, so I put a timer so that you can see the animation little by little but it still dont work :/
Here is my code:
class Animation
{
private int x_dropGridToBottom;
private Grid grid_dropGridToBottom;
private System.Timers.Timer t;
public Animation()
{
t = new System.Timers.Timer();
t.Interval = 500;
}
private void TimerElapsed_DropGridToBottom(object sender, ElapsedEventArgs e)
{
while (x_dropGridToBottom > 0)
{
x_dropGridToBottom--;
Application.Current.Dispatcher.Invoke(() =>
{
grid_dropGridToBottom.Margin = new Thickness(0, x_dropGridToBottom, 0, x_dropGridToBottom);
});
}
if (x_dropGridToBottom == 0)
t.Stop();
}
internal void DropGridToBottom(Grid grid, Window window)
{
grid.Margin = new Thickness(0, window.Height, 0, window.Height);
// 0 x 0 x (x = window.height)
// x = -y (y=412)
// x (=) 0
grid_dropGridToBottom = grid;
x_dropGridToBottom = Convert.ToInt32(window.Height);
t.Elapsed += new ElapsedEventHandler(TimerElapsed_DropGridToBottom);
t.Start();
}
}
And here is the code when I press the button that is supposed to start the animation :
private void Button_Click(object sender, RoutedEventArgs e)
{
Animation anim = new Animation();
anim.DropGridToBottom(grid_2, this);
}
Somebody has an idea of why and how I can make my grid move little by little but not directly in one go (as it does nowadays).
Thank you
I am creating a C# WinForm application and I want to detect mouse movement when the mouse is outside the form.
I already tried to create new thread that continually calculates the mouse coordinates, it work well as a job, but it uses while(true). It's really inefficient for CPU.
Edit (missunderstanding from first time) :
Working example -->
private void MainForm_MouseLeave(object sender, EventArgs e)
{
this.Cursor = new System.Windows.Forms.Cursor(System.Windows.Forms.Cursor.Current.Handle);
System.Windows.Forms.Cursor.Position = new Point(0, 0);
MoveCursor(300, 300);
MoveCursor(400, 400);
}
private void MoveCursor(int X, int Y)
{
this.Cursor = new System.Windows.Forms.Cursor(System.Windows.Forms.Cursor.Current.Handle);
System.Windows.Forms.Cursor.Position = new Point(X,Y);
}
I've got a smaller image in my form. When the user hovers over the image it brings up a larger view of the image (that follows the mouse, but stays a certain distance from the mouse). In order to do this I am generating a Form with no FormBorderStyles when the cursor hovers the image.
The problem I'm running into is that the first form doesn't seem to detect any longer that the mouse is hovering or leaving the PictureBox once the form activates. The Form also doesn't follow the cursor.
Here is the slimmed down version of what I've got:
C#
bool formOpen = false;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.MouseHover += pictureBox1_MouseHover;
pictureBox1.MouseLeave +=pictureBox1_MouseLeave;
}
void pictureBox1_MouseHover(object sender, EventArgs e)
{
if (formOpen == false)
{
Form form = new Form();
form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
form.BackColor = Color.Orchid;
//Show the form
form.Show();
form.Name = "imageForm";
this.AddOwnedForm(form);
//Set event handler for when the mouse leaves the image area.
//form.MouseLeave += form_MouseLeave;
//Set the location of the form and size
form.BackColor = Color.Black;
form.Dock = DockStyle.Fill;
form.Size = new Size(30, 30);
form.BackgroundImageLayout = ImageLayout.Center;
this.TopMost = true;
formOpen = true;
form.Location = new Point(Cursor.Position.X, Cursor.Position.Y);
}
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
//MessageBox.Show("Worked");
}
}
The MouseLeave (and other events) was not recognized because the opening of the popup window and especially making it topmost=true took away the focus from the original form and its PictureBox.
It also didn't move because not code for moving was provided..
Here are a few changes that will make the form move:
You need a reference to it at the form1 level
you need to move it in the MouseMove event
Note that Hover is a once-only type of event. It fires only once until you leave the control.. (Note: Setsu has switched from Hover to Enter. This works fine, but lacks the short delay before showing the 2nd Form. If you want that back you can either switch back to Hover or you can fake the hover delay by a Timer, which is what I often do.)
// class level variable
Form form;
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.MouseEnter += pictureBox1_MouseEnter;
pictureBox1.MouseLeave +=pictureBox1_MouseLeave;
pictureBox1.MouseMove += pictureBox1_MouseMove; // here we move the form..
}
// .. with a little offset. The exact numbers depend on the cursor shape
void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if ((form != null) && form.Visible)
{
form.Location = new Point(Cursor.Position.X + 5, Cursor.Position.Y + 5);
}
}
void pictureBox1_MouseEnter(object sender, EventArgs e)
{
// we create it only once. Could also be done at startup!
if (form == null)
{
form = new Form();
form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
//form.BackColor = Color.Orchid;
form.Name = "imageForm";
this.AddOwnedForm(form);
form.BackColor = Color.Black;
form.Dock = DockStyle.Fill;
form.Size = new Size(30, 30);
form.BackgroundImageLayout = ImageLayout.Center;
//this.TopMost = true; // wrong! this will steal the focus!!
form.ShowInTaskbar = false;
}
// later we only show and update it..
form.Show();
form.Location = new Point(Cursor.Position.X + 5, Cursor.Position.Y + 5);
// we want the Focus to be on the main form!
Focus();
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
if (form!= null) form.Hide();
}
MouseHover = Occurs when the mouse pointer rests on the control. (msdn)
Try MouseMove instead.
Currently I am doing this in my code,
playbackElement1.AutoPlay = true;
playbackElement1.SetSource(stream, this.m_recordStorageFile.FileType);
playbackElement1.Position = new TimeSpan(0, 0, 0, 0, 5000);
playbackElement1.Play();
It doesn't work, checking for a video longer than 5 secs.
There are two problems. First, MediaElement can only set the position once the media is loaded, determined by handling the MediaOpened event. Secondly, not all media is seekable. Check by calling CanSeek. Use something like:
playbackElement1.AutoPlay = true;
// Will fire after the media has loaded
playbackElement1.MediaOpened += (source, args) =>
{
MediaElement player = (MediaElement) source;
if (player.CanSeek)
{
player.Position = new TimeSpan(0, 0, 0, 0, 5000);
}
}
playbackElement1.SetSource(stream, this.m_recordStorageFile.FileType);
Once loaded, use the NaturalDuration property to see the length of the media, converting it to a TimeSpan using HasTimeSpan and TimeSpan properties if needed.
In a nutshell, you will need to add a Slider underneath the MediaElement just like in any video player...
- the Slider will update the player current position
- the Timer will update the slider every 300 millisecond with the current player position
Code:
<Slider x:Name="videoSlider" Thumb.DragStarted="videoSlider_DragStarted" Thumb.DragCompleted="videoSlider_DragCompleted" Margin="10,0,10,30" Height="18" VerticalAlignment="Bottom"/>
<MediaElement x:Name="videoPlayer" Margin="4,59,152,53" Volume=".5" MediaOpened="videoPlayer_MediaOpened">
[This is picture for the Media-Element with the Slider][1]
Now we have a media element and a slider... Next: C# Code :)
public partial class MainWindow : Window
{
bool isSeekingMedia = false;
DispatcherTimer seeker; // the timer to update the Slider
public MainWindow()
{
InitializeComponent();
player = new MediaPLayer();
IsPlaying(false);
seeker = new DispatcherTimer();
seeker.Interval = TimeSpan.FromMilliseconds(200);
seeker.Tick += Seeker_Tick;
}
///Seeker_Tick will update the Slider position while the video is playing
private void Seeker_Tick(object sender, EventArgs e)
{
try
{
MediatimeCounter.Content = String.Format("{0:hh}:{0:mm}:{0:ss}/{1:hh}:{1:mm}:{1:ss}", videoPlayer.Position, videoPlayer.NaturalDuration.TimeSpan);
if (!isSeekingMedia)
{
videoSlider.Value = videoPlayer.Position.TotalSeconds;
}
}
catch (Exception ex) { }
}
//This code is going to set Seeking to true to avoid playing the video if the user is changing the slider position... it kinda causes a performance issue.. so it's better to update the video position once the slider dragging event is completed.
private void videoSlider_DragStarted(object sender, RoutedEventArgs e)
{
isSeekingMedia = true;
}
//and this code is to update the video position based on the slider value.
private void videoSlider_DragCompleted(object sender, RoutedEventArgs e)
{
if (videoPlayer.Source != null)
{
isSeekingMedia = false;
this.videoPlayer = player.SeekVideo(videoPlayer, videoSlider.Value);
}
}
Is there any way to capture the time interval between mouse wheel scroll start and stop? Actually I want to capture the interval between the scrolling start and stop when I very quickly scroll the mouse wheel.
I have already looked at MouseWheel event but it don't fulfill my requirement. In senes that it always gives a value of Delta 120 or -120 but i want to call a function depending on the speed of the mouse scroll for example when i scroll the mouse normally i want to perform function 1 and when i scrolled the mouse very quickly i want to perform the function 2. In other words is there any way to distinguish between the mouse scroll high and normal speed.
Any advice will be appreciated.
can't you capture the mouse wheel events and see how long between them. Basically start a timer when you get a mouse wheel event and then in the next event see what the timer is at (and so how long has elapsed between the events) to determine the speed the wheel is being turned at? If the elapsedtime is smaller than a certain threshold, perform function2 and if it is faster than a certain threshold perform function 1.
You will probably have to set it to perform function 1 if the timer goes off in case they only do a single scroll.
In fact you might be able to do it this way:
start a timer (with an interval that indicates slow mouse wheeling) in the mouse wheel event, then if the timer goes off perform function 1. If the mouse wheel event happens again before the timer has gone off then reset the timer and increment a counter (to keep track of the number in wheel events since you did stuff) then start a second (longer) timer. if the counter is greater then a certain threshold perform function 2. When the second timer elapses, reset the counter. Something along those lines should give you the ability to fire function 1 when slow wheel turning and function 2 when the wheel is rapidly turned through a few 'clicks'.
this code should give a (very dirty) indication of the sort of thing I was thinking of. After playing a little I'm not really sure it's a good solution though....
private void mouseWheelHandler (object sender, MouseEventArgs e)
{
slowTimer.Enabled = false;
slowTimer.Stop ();
slowTimer.Interval = 200;
slowTimer.Start();
slowTimer.Enabled = true;
m_counter++;
Trace.WriteLine(string.Format("counter={0}", m_counter));
if (fastTimer.Enabled==false)
{
fastTimer.Enabled = true;
fastTimer.Interval = 150;
fastTimer.Start ();
}
if (m_counter>5)
{
Trace.WriteLine("called method 2");
m_counter = 0;
fastTimer.Stop ();
slowTimer.Enabled = false;
slowCheckTimer.Stop ();
slowCheckTimer.Interval = 250;
slowCheckTimer.Start();
slowCheckTimer.Enabled = true;
}
}
private void slowTimer_Tick(object sender, EventArgs e)
{
Trace.WriteLine("slow timer ticked");
if (slowCheckTimer.Enabled==false)
{
Trace.WriteLine ("called method 1");
}
slowTimer.Enabled = false;
}
private void fastTimer_Tick(object sender, EventArgs e)
{
fastTimer.Enabled = false;
Trace.WriteLine("fast timer ticked");
m_counter = 0;
fastTimer.Stop ();
}
private void slowCheckTimer_Tick(object sender, EventArgs e)
{
Trace.WriteLine("slow check timer ticked");
slowCheckTimer.Stop ();
slowCheckTimer.Enabled = false;
}
Take a look at the Control.MouseWheel event.
As suggested by the Sam Holder i am posting here a modified verion of his advice to help other programmers facing the same problem.
public partial class Form1 : Form
{
int m_counter = 0;
public Form1()
{
InitializeComponent();
// Attach Mouse Wheel Event
this.MouseWheel += new MouseEventHandler(Form1_MouseWheel);
}
void Form1_MouseWheel(object sender, MouseEventArgs e)
{
// Refresh Slow Timer
slowTimer.Enabled = false;
slowTimer.Stop();
slowTimer.Interval = 150;
slowTimer.Start();
slowTimer.Enabled = true;
// Incremenet counter
m_counter++;
// Start Fast Timer
if (fastTimer.Enabled == false)
{
fastTimer.Enabled = true;
fastTimer.Interval = 50;
fastTimer.Start();
}
// If this returns true call
// the fast scroll implementation
if (m_counter > 4)
{
Console.WriteLine("Quick Method Called");
m_counter = 0;
fastTimer.Stop();
slowTimer.Enabled = false;
slowCheckTimer.Stop();
slowCheckTimer.Interval = 200;
slowCheckTimer.Start();
slowCheckTimer.Enabled = true;
}
}
private void slowTimer_Tick(object sender, EventArgs e)
{
if (slowCheckTimer.Enabled == false)
{
Console.WriteLine("Slow Method Called");
}
slowTimer.Enabled = false;
}
private void fastTimer_Tick(object sender, EventArgs e)
{
fastTimer.Enabled = false;
m_counter = 0;
fastTimer.Stop();
}
private void slowCheckTimer_Tick(object sender, EventArgs e)
{
slowCheckTimer.Stop();
slowCheckTimer.Enabled = false;
}
}