Change mediaelement Source Based on Actions - wpf

I have a WPF 4 and VB.net 2010 project. I am playing videos in a single mediaelement. This is what I need to do:
When the window first opens, I have the first video play just fine. However, it is after this video plays that I run into trouble figuring out how to do the following.
I need the video source to change immediately following a single play through of any video, and I need this video (henceforth referred to as an "ambient" video) to loop forever.
When a certain event happens, I need to change the video source again, have it play once through, and then go back to looping ambient video in step 1.
Here is the rub, however. Many of the video triggers are inside of If-Then or Select Case statements in code behind, so I'm not exclusively using simple WPF events such as "MouseUp" or "MouseEnter".
Also, all videos must play in the same mediaelement, for performance reasons.
Thank you in advance!
How do I do this?

The Source of the media element is a DependencyProperty, as such any changes to it will be immediately reflected in the UI.
If you combine this with the MediaEnded event that is fired, you can set the Source and your problem is solved.
When you hit the triggers in code, you can either call a method or fire an event. You will have to use some semblance of a State Pattern to deal with the other logic. As an aside, check out Programming Without Ifs, it's an awesome intro on how to avoid insane conditional logic.

I set the mediaelement's LoadedBehavior to "Play" and Unloadedbehavior to "Stop", then I was able to just change the source of the mediaelement itself in code, and put the video I needed played after every video into the MediaEnded event.
It turns out that MediaEnded does not fire automatically when the LoadedBehavior is set to "Manual", unless "Stop" is explicitly called in code.
I hate accepting my own answers, so Nate Noonen gets the bounty (he was going down the right alley originally)! TY!

Related

Playing music in Silverlight + XNA application

I have several issues with playing music in a Silverlight+XNA combined application. It has several Silverlight pages and the "game" page rendered in XNA.
First, I added the following code to the OnNavigatedTo event of the main Silverlight page:
var song = (Application.Current as App).Content.Load<Song>("Music/Menu");
MediaPlayer.Play(song);
MediaPlayer.Volume = 0.9f;
MediaPlayer.IsRepeating = true;
The music starts playing, however the application fails with the following exception that has no evident callstack hints:
InvalidOperationException occured
FrameworkDispatcher.Update has not been called. Regular FrameworkDispatcher.Update calls are necessary for fire and forget sound effects and framework events to function correctly.
Secondly, I have a few Silverlight-based windows rendered using UIElementRenderer. When the need arises, I change the control's IsEnabled flag to true and start drawing it on the screen. This makes the music stop playing with a fadeout for no apparent reason and it wouldn't even start back when I close the Silverligh window.
Navigating from the frame and back to it makes things even worse. The same call to MediaPlayer.Play(song) says that the song has been disposed, even though I load it from the ContentManager anew.
Please see this StackOverflow question — answer is pretty clear. In short, you have to call FrameworkDispatcher.Update() before using XNA media libraries.

Have callback function for button while it is pressed on wp7 Silverlight

In Windows Phone 7 Silverlight is there a way to be able to have a button that while I have it selected it calls on a callback function. Either that, or have to functions one for when the button is selected and one for when the button is released. Any ideas as how to do this?
Note that I have already looked at the the toolkit, and the gestures they provide do not include this.
Thanks!
you could look at this in-depth article on gestures:
http://windowsphonegeek.com/articles/WP7-GestureService-in-depth--key-concepts-and-API
specifically the Tap and hold gesture might work for you.
These events would be applicable:
•GestureBegin
The GestureBegin event.
public event EventHandler<GestureEventArgs> GestureBegin;
•GestureCompleted
The GestureCompleted event.
public event EventHandler<GestureEventArgs> GestureCompleted;
On MouseLeftButtonDown start a timer that will Tick until Button is released. Also, you have a control on timer tick Interval
Are you trying to create an action that is similar to the list item tilt effect. or like the video scrub bar. both of those operate when finger is down on the screen, then return to previous state when you remove your finger?
For future reference, and to save some future soul the frustration of why the heck MS didn't implement this in the first place as part of their SDK...
I ended up solving this problem by using ManipulationStarted to record the start time, and ManipulationEnd to record the end time of the gesture, and a separate thread to keep track of the ticks in between.

Windows Phone 7.1 - Media Element not playing

Windows Phone 7.1/7.5/Mango app.
I have four different MediaElements on the page.
One is played upon Load of the page.
Rest 3 I Play() it upon leftMouseButtonClick on different image element on the page.
I call Stop() in the MediaEnded event handler.
Issue: The last mediaElement in the top-down order won't play. So it's not the element itself bu the order of the element that is behaving weird.
I have read this where it talks about a single MediaElement which I don't understand.
Does anyone has any ideas on this?
Note: I don't have to play all sound at the same time. Only one sound at a time.
I found one reference that talks having single MediaElement only and dynamically set the Source in the code. I haven't tried it yet, will do soon.
To confirm your last sentence, you can only have one MediaElement per page. You'll have to consider changing the source from the code-behind (or using data-binding) instead of having a MediaElement for each piece of audio. Having multiple MediaElements won't throw an error, but it will just override the behaviour of the previously added one (like you're experiencing).
To set the audio from the code-behind, you can use either the SetSource (which accepts a stream) method, or the Source property which reads a Uri.
In my case, I get the error at the 6th media element. I try to put 14 Media Elements in a project (just to see what happens). You could also use SoundEffect from XNA if you really need to have a lot of sources playing at the same time or something

How can I play multiple sounds with MediaElement?

I can't play more than one sound per page.
I created 2 instances of MediaElement, and each one, I set to play, but it only play one!
How can I solve this please?
If you add a reference to Microsoft.Xna.Framework to you project, you can use SoundEffect.Play to play mulitple sounds at the same time.
Add a event handler for MediaEnded to your first MediaElement control. In that event handler, start playing the sound on the second MediaElement using mediaElement2.Play().

Drop outside the control

I'm improving standart WPF TabControl. I want to add undocking functionality to it:
user drags the page just outside the TabControl and this page undocks in the window.
I want two events in this control - PageDragStart (raises when the page dragged outside) and PageDragEnd (raises when the page dropped outside)
I've got no problem with the first event.
But the second... OnDrop doesn't call, because the item dropped outside the tabcontol container. How can I know that it was dropped?
P.S. I want a universal control (so, undocking functionality shouldn't be connected and hardcoded with the window tabcontrol is placed or something like this)
Why use DoDragDrop at all? As I was reading your description, using Mouse.Capture by itself seemed the obvious solution:
Handle OnMouseLeftButtonDown on the tab and start capture
Handle OnMouseMove on the tab and update the cursor based on hit testing
Handle OnMouseLeftButtonUp on the tab, and stop the capture and make the appropriate change
The reasons you might ever consider DoDragDrop over simple mouse capture are:
Integration with Windows' OLE drag and drop so you can drag and drop between applications and technologies
Modal nature of DoDragDrop call (which actually seems to be more of a disadvantage to me)
Automated hit testing of targets
Standardized "drop operation" API to allow unrelated applications to handle copy vs move, etc.
You apparently don't need the OLE integration or multi-application support and you want to customize the hit testing, so it seems that DoDragDrop has no advantages over directly handling the mouse capture.
I solved the problem - in rather brutal and unsafe way. But for it's gonna work as the temporary solution.
Well, when I'm raising PageDragStart event, I call Mouse.Capture(this, CaptureMode.SubTree);
When the page is dropped somewhere - DoDragDrop throws different exceptions (COMException, NullReference (I couldn't find which object is null) and some others I don't remember).
I catch exception and call PageDragEnd event (if the property IsPageDraggingOut set to true).
As far as you can see this solution is really dirty and bad. But it works.
So, any other ideas (or some ideas how to work with Mouse.Capture properly)?

Resources