I have 2 custom controls in my silverlight application and each one is having its own animations. I want to play all of the animations in order but when they play at the same time, the animations are not playing properly. How can I put some delay between them?
private void button1_Click(object sender, RoutedEventArgs e)
{
Dispatcher.BeginInvoke(() => {
myCustomControl1.Play();
Thread.Sleep(200);
Dispatcher.BeginInvoke(() => { myCustomControl2.Play(); });
}
I'm assuming your controls are using a StoryBoard to play the animations. StoryBoard has a "Completed" event that fires after it completes running. So, you could do something like:
public class CustomControl:Control
{
public override void ApplyTemplate()
{
_storyBoard=GetTemplateChild("AnimationStoryBoard") as Storyboard;
_storyBoard.Completed+=OnCompleted;
}
public event eventhandler AnimationCompleted;
public void Play()
{
_storyBoard.Begin();
}
private void OnCompleted(object sender, EventArgs args)
{
if(AnimationCompleted!=null)
AnimationCompleted(this,EventArg.Empty);
}
}
What you can then do is chain your animations together:
myCustomControl1.AnimationCompleted+=RunSecondAnimation;
myCustomControl1.Play();
private void RunSecondAnimation(object sender, EventArgs args)
{
myCustomControl2.Play();
}
Now we can guarantee that animation 2 will always happen after animation 1.
Related
So i have 2 forms, one is called "musica" and its playing a music (this form is invisible) and the other is called "Form1" and gives the option to stop and start the music with radio buttons.
The problem is that the radio buttons are working, but the video continues even if i click on "radionButton2" and if i use the "stop()" function on "musica_load" the music stops so i don't think the problem is from there either.
What is my mistake here?
Form1 code:
musica mus = new musica();
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (radioButton1.Checked == true)
{
mus.play();
}
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
if (radioButton2.Checked == true)
{
mus.stop();
}
}
musica code:
public void play()
{
axWindowsMediaPlayer1.Ctlcontrols.play();
}
public void stop()
{
axWindowsMediaPlayer1.Ctlcontrols.stop();
}
// Form1.cs
musica mus;
public Form1()
{
InitializeComponent();
mus = new musica();
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (radioButton1.Checked == true)
{
mus.Play(); ;
}
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
if (radioButton2.Checked == true)
{
mus.Stop();
}
}
//Musica.cs
public musica()
{
InitializeComponent();
}
public void Play()
{
MessageBox.Show("Play");
}
public void Stop()
{
MessageBox.Show("Stop");
}
This works fine there must be some problem with the Play and Stop methods.
Answer: The problem was that i was opennig both forms simultaneously at the start of the program and for some reason they can't work between each other, if i open the musica.cs in Form1_load everything works!
I am a beginner in C# and WPF and I am building this project in which I have to trigger when the mouse is moved. Under some conditions, I have to use it as a background worker. I want to call the mouse_Moved method in the background, but I don't know how to actually do that . Can anyone help me please? This is my code so far:
public MainWindow()
{
InitializeComponent();
mouse = new MouseInput();
mouse.MouseMoved += mouse_MouseMoved;
}
void mouse_MouseMoved(object sender, EventArgs e)
{
//The code that I need
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
//where I want to call the mouse_Moved method
}
Create a method and call it from both:
void mouse_MouseMoved(object sender, EventArgs e)
{
DoMouseMovedWork();
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
DoMouseMovedWork();
}
private DoMouseMovedWork()
{
//The code I need
}
So I have a function inside of a button that I want to trigger as soon as my application starts, and I am doing it by this:
public partial class App : Application
{
private void App_OnStartup(object sender, StartupEventArgs e)
{
//get button reference
Button btn = ((MainWindow)Current.MainWindow).btnJSON;
//programmatically simulate button click
ButtonAutomationPeer peer =
new ButtonAutomationPeer(btn);
IInvokeProvider invokeProv =
peer.GetPattern(PatternInterface.Invoke)
as IInvokeProvider;
invokeProv.Invoke();
}
}
However, this leads be to a nullReferenceExeption. How do I achieve this, i.e. invoking the fucntion on App stratup or simulate the button click?
Here is the button signature:
public void btnJSON_Click(object sender, RoutedEventArgs e)
{
...
}
Thanks.
Instead of trying to invoke the button click, just call the method that the button click invokes.
public partial class App : Application
{
private void App_OnStartup(object sender, StartupEventArgs e)
{
((MainWindow)Current.MainWindow).DoStuff();
}
}
In your MainWindow.xaml.cs:
public void DoStuff()
{
// TODO: Do Stuff
}
Just have your button click handler call that method.
public void btnJSON_Click(object sender, RoutedEventArgs e)
{
DoStuff();
}
Don't call the button click if all you want is to run some code. If your button's click handler looks like:
public void btnJSON_Click(object sender, RoutedEventArgs e)
{
DoSomeInterestingStuff();
}
Then just call that method from your startup method:
private void App_OnStartup(object sender, StartupEventArgs e)
{
DoSomeInterestingStuff();
// other stuff to do here
}
I am trying to figure out how to make it that when my timer ticks, it performs a bidder00_TextChanged, or something like that.
Is this even possible to do? and if it isn't, is there any other way to do it?
I tried to search Google for it but i didn't get any results, if you find anything that i missed please post it here.
I don't really have any code but here it is:
private void bidder00_TextChanged(object sender, EventArgs e)
{
if (bidder00.Text == addbidder1.Text)
{
bidBtn1.PerformClick();
}
}
That is my TextChanged Event
My timer doesn't have any code because it is going to perform the bidder00_TextChanged Event.
You could create a method Perform() and call it from within your event handlers :
private void timer1_Tick(object sender, EventArgs e)
{
Perform();
}
private void bidder00_TextChanged(object sender, EventArgs e)
{
Perform();
}
private void Perform()
{
if (bidder00.Text == addbidder1.Text)
{
bidBtn1.PerformClick();
}
}
I assume you have coupled your actual logic with your click event which is not a good idea. Separate the code out into a separate function and have both parts of the application call the same code e.g.
private void SubmitBid()
{
// code you want to execute
}
private void OnSubmitBid()
{
// confirm whether we can actually submit the bid
if (bidder00.Text == addbidder1.Text)
{
SubmitBid();
}
}
private void Timer1_OnTick(object sender, EventArgs e)
{
// trigger code from timer
OnSubmitBid();
}
private void bidder00_TextChanged(object sender, EventArgs e)
{
// trigger code from text change
OnSubmitBid();
}
private void btnBid_Click(object sender, EventArgs e)
{
// trigger code from button press
OnSubmitBid();
}
Notice all the UI controls trigger the same code. There is an extra call in there for the text control validation (i.e. OnSubmitBid()) - if this wasn't required then you would just call SubmitBid directly.
I am creating a WP7 application that requires various sound effects to be played (on button press) over looped background music. The background music is initiated by pressing Button 1 and loops fine. When I press button3 (triggers a sound effect), the sound effect overlays on the background music fine on first press. However, when I press button3 again, the background music stops. I cannot figure out why this might be happening!? I have pasted the relevant portions of code below. Would appreciate any help.
public partial class MainPage : PhoneApplicationPage
{
SoundEffect soundEffect;
Stream soundfile;
// Constructor
public MainPage()
{
InitializeComponent();
}
static protected void LoopClip(SoundEffect soundEffect)
{
{
SoundEffectInstance instance = soundEffect.CreateInstance();
instance.IsLooped = true;
FrameworkDispatcher.Update();
instance.Play();
}
}
public void PlaySound(string soundFile)
{
using (var stream = TitleContainer.OpenStream(soundFile))
{
var effect = SoundEffect.FromStream(stream);
effect.Play();
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
soundfile = TitleContainer.OpenStream("BackgroundMusic.wav");
soundEffect = SoundEffect.FromStream(soundfile);
LoopClip(soundEffect);
}
private void button3_Click(object sender, RoutedEventArgs e)
{
PlaySound("sound3.wav");
}
}
}
This should work if you are always working with Instances so change your code to this and it should clear up the problem:
public partial class MainPage : PhoneApplicationPage
{
SoundEffectInstance loopedSound = null;
// Constructor
public MainPage()
{
InitializeComponent();
}
static protected void LoopClip(SoundEffect soundEffect)
{
loopedSound = soundEffect.CreateInstance();
loopedSound.IsLooped = true;
loopedSound.Play();
}
public void PlaySound(string soundFile)
{
SoundEffect sound = SoundEffect.FromStream(Application.GetResourceStream(new Uri(soundFile, UriKind.Relative)).Stream);
SoundEffectInstance instance = sound.CreateInstance();
instance.Play();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
SoundEffect sound = SoundEffect.FromStream(Application.GetResourceStream(new Uri(#"BackgroundMusic.wav", UriKind.Relative)).Stream);
LoopClip(sound);
}
private void button3_Click(object sender, RoutedEventArgs e)
{
PlaySound("sound3.wav");
}
}
The above example assumes your sound files are set with Build Action = Content and are in the top level directory.
You will need to play each sound from a separate thread.
What seems to be happening here is that the different Play method calls are interfering with each other since they are in the same thread.
Try just putting the background music in a separate thread and see if that solves the problem you mention in the question. If so, split the others out as well.