Windows Phone - OnNavigatingFrom - problem - silverlight

I believe this is just a problem for me, due to my lack of programming ability. I am currently exploring transitions between page navigation with Windows Phone apps. I was originally using storyboards, and completed event handlers to have my pages animate on and off screen. These leads to the a problem when you want to navigate to many pages from one page, using the same transition.
So I have started looking at OnNavigatedTo, and OnNavigatingFrom events and while it is working nicely for OnNavigatedTo, the later just wont work. It seems the Microsoft.Phone.Navigation assembly does not contain OnNavigatingFrom, and referencing System.Windows.Navigation, compiles ok, but I cant get pages to animate off upon navigation.
I have a button on my Page2, which I want to go back to my MainPage (after I over-rided the back key with a message box for testing). I have transitions made on the page, and I have this as the event handler code...
private void btnP2_BackToP1Clicked(object sender, System.Windows.RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
With this code for the OnNavigatedTo and OnNavigatingFrom events...
protected override void OnNavigatedTo(PhoneNavigationEventArgs e)
{
PageTransition_In.Begin();
}
// //
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
PageTransition_Out.Begin();
base.OnNavigatingFrom(e);
}
I have the feeling that OnNavigatingFrom may not(yet) be supported for Windows Phone Apps. OnNavigatedFrom is part of Microsoft.Phone.Navigation, but it only performs actions once the page is no longer active, which is too late to perform any animation effects.

I believe that you need to add an event that captures the transition completion. Check out the demo that Microsoft provides for a list view application.

The approach you are taking is not quite correct. Instead it is better to alter the page frame to know how to do transitions between pages. You can see a good examples of this on a Channel 9 vid or on Avi Pilosof's blog.
Example:
<ControlTemplate x:Key="TransitioningFrame" TargetType="navigation:PhoneApplicationFrame">
<Border>
<toolkit:TransitioningContentControl
Content="{TemplateBinding Content}" Transition="DownTransition" />
</Border>
</ControlTemplate>

I am baffled why we need to roll our own smooth transitions for WinPhone7, but there it is. Jeff Brand (SlickThought.net) seems to have the best solution so far. Here is a nice article with a walkthrough video and sample code, though his sample code in the article was for the April CTP and appears to be broken in the Beta tools.

Related

tapjoy issue with video playing

I am having one Windows phone game, built using Silverlight. In this game, I want to add TapJoy. I have downloaded their latest SDK and follow all their steps to intigrate the it within my app.
In the game, I am using silverlight as a main frame work and Global Media Element to play contious Background Music. I am using
(Microsoft.Xna.Framework.Media) (Microsoft.Xna.Framework) namespace.
Using them, I use following methods to play contious background sound.
DispatcherTimer and FrameworkDispatcher.Update
Now, when I click tap joy button to open their offers, they load fine; however, when I open the video within the offer, they show us following error “Video cannot be played, please try again.”
Based on some research and study, I tried few things and found that,
a) I need to set Media Element and DispatcherTimer is to null.
b) The application is sent in background (deactivated) and then I open it again (activated), the video is coming fine. I checked and found that Media Element and DispatcherTimer were set to null properly.
But if I follow step one only, and do not send the app in background, the media element and dispatcherTimer are not set to null.
Can anyone please help me and answer me following
a) Am I doing anythign wroing with this?
b) Can I do anything so that when tap joy button is clicked, my application is sent to background automatically since this can solve the issue.
c) I am using gc.collect() after setting value to null but still it is not getting destroyed.
Thanks in advance,
David Jacob.
I'm trying to follow along with what you've said. I personally would've set it up differently, but I'll get to that later.
I have a setup that is similar to your description, and it works with Tapjoy's Videos.
Firstly, you mentioned that it was a Silverlight game, so I created a new Windows Phone Application project under the Silverlight For Windows Phone template, in VS 2010.
Setup Dispatcher:
I added the following class to my project (typically called XNAFrameworkDispatcherService.cs from this msdn example: http://msdn.microsoft.com/en-us/library/ff842408.aspx)
public class XNAFrameworkDispatcherService : IApplicationService
{
private DispatcherTimer frameworkDispatcherTimer;
public XNAFrameworkDispatcherService()
{
this.frameworkDispatcherTimer = new DispatcherTimer();
this.frameworkDispatcherTimer.Interval = TimeSpan.FromTicks(333333);
this.frameworkDispatcherTimer.Tick += frameworkDispatcherTimer_Tick;
FrameworkDispatcher.Update();
}
void frameworkDispatcherTimer_Tick(object sender, EventArgs e)
{
FrameworkDispatcher.Update();
}
void IApplicationService.StartService(ApplicationServiceContext context)
{
this.frameworkDispatcherTimer.Start();
}
void IApplicationService.StopService()
{
this.frameworkDispatcherTimer.Stop();
}
}
In order to start this service, make sure you've added it to your App.xaml.
Add an attribute to your Application element that points to your namespace, something like this:
xmlns:s="clr-namespace:WindowsPhoneApplication;assembly=WindowsPhoneApplication">
Then within your block add the following:
<s:XNAFrameworkDispatcherService />
Play Music:
Now about playing a looping music file.
In the MainPage.xaml.cs, I've setup a Microsoft.Xna.Framework.Media.Song to loop when the page is navigated to, using the Microsoft.Xna.Framework.Media.MediaPlayer.
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
Tapjoy.TapjoyConnect.Instance.RequestTapjoyConnect("your-app-id", "your-secret-key");
try
{
Song song = Song.FromUri("example", new Uri("/example.wma", UriKind.Relative));
MediaPlayer.IsRepeating = true;
MediaPlayer.Play(song);
}
catch (Exception)
{
System.Diagnostics.Debug.WriteLine("Can't load sound");
}
}
I also set it to stop playing music, when the page is navigated away from.
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
MediaPlayer.Stop();
}
I then created a button to launch the Tapjoy Offer wall.
private void button1_Click(object sender, RoutedEventArgs e)
{
Tapjoy.TapjoyConnect.Instance.ShowOffers();
}
Summary:
What happens now, is when your Application starts up, it launches the XNAFrameworkDispatcherService that ticks at approximately 30fps. This will dispatch messages that are in the XNA Framework Queue for you. This is only needed in silverlight applications that are using audio/media services from XNA.
When the MainPage is navigated to, you ping Tapjoy with the Connect call, and you load up your Song to loop.
Normal gameplay can progress now, and when the Show Offers button is clicked, Tapjoy will navigate away from your page, causing on navigated from event to fire, and the MediaPlayer will stop your song.
Ideas for your game:
You might want to consider creating a new project and using the "Windows Phone Silverlight and XNA Application" option. VS2010 will create a blank project with a Content manager already setup, so you can use sounds and images with the XNA pipeline, which I've found to be easier.
Good luck, and remember that Tapjoy provides support for these issues as well. Just email them at support#tapjoy.com, or use the Tapjoy Developer group at: https://groups.google.com/group/tapjoy-developer?hl=en

wpf dual monitor application?

I'm very new to WPF. I want to create a dual monitor/projector application. What I want to do is have the "presenters screen" on one monitor and another panel on the secondary monitor, similar to how powerpoint works. I'm struggling to wrap my mind around the panels and XAML. So what I'm after is user clicks on a button on screen1 and information gets updated on screen2.
I'm using this code:
this.Width = System.Windows.SystemParameters.VirtualScreenWidth;
this.Height = System.Windows.SystemParameters.VirtualScreenHeight;
this.Top = 0;
this.Left = 0;
to set the width and height of the screen.
Edit:
The later goal is to cause screen2 to retrieve items out of a database based on the selection on screen1
Question: tutorials, places to go, nudges on how to update monitor2 from a button on monitor1
Short Answer
Create a view model that shared between two views; make one of the views the master (makes the changes) and the other pure presentation. The views are new windows. Initially do not be concerned with the window position (we'll get to that later) just get the shared viewmodel working.
Tip: research the MVVM pattern. Google has a lot of articles on the subject.
Long Answer
After you have researched MVVM and created a few example applications (from scatch or using a framework), below are few additional features you want implement to create the "powerpoint-like" application.
Fullscreen Mode
At the very least you will want the presentation window to be full screen. To achieve this, you set the WindowStyle to None and AllowsTransparency to True.
If you want to make the second window also fullscreen you may need to do some Win32 overrides to get the window to maximize properly without covering the taskbar (post a comment if you want to know how to do this).
Detect Multiple Monitors
Get the size and position of the monitors using Win32 Interop commands. There will be plenty of articles on the Internet that will help you with this (or post another StackoverFlow question).
This would be a neat™ feature as it will position the two windows correctly (use the secondary screen as the presentation).
That is all that I can think of now, post-back if you any questions on MVVM or any of the additional points above.
1) You should have 2 Windows, the way this looks I'd make monitor2 a child window of monitor1 (after all, it is a child ;)
What i mean by that, is that StartupUri in App.xaml should point to monitor1, and in monitor1's constructor, you should create an instance of monitor2 (which would be a singleton if i were to do it).
2) To maximize a window on the second screen:
Subscribe to the Loaded event of the window (in code-behind), and set
private void Window_Loaded(object sender, RoutedEventArgs e) {
WindowState = WindowState.Maximized;
}
More info (and source): here
3) As to how to make monitor2 react when you set something in monitor1, make monitor1 and monitor2 bind to the same ViewModel, only they show different stuff.
Hope this helps!

Go back in a specific panorama/pivot item?

I would like to know if is it possible when a user press "back button" to go in a specific pivot or panorama item on WP7 sdk.
You can make sure that the user is always returned to the item they left by overriding the OnNavigatedFrom and OnNavigatedTo events and using the PhonePageApplication.State property to store the selected item. This will work even if the app is tombstoned while on a different page.
Something like:
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
State.Add("selectedPivot", myPivot.SelectedIndex);
base.OnNavigatedFrom(e);
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
myPivot.SelectedIndex = (int)State["selectedPivot"];
base.OnNavigatedTo(e);
}
Please note the above is untested, requires additonal checks and error handling, etc. but should be enough to get you started.
It would be possible to implement this approach by implementing the OnBackKeyPress override in your page, however, this would not be consistent with back button behavior in Windows Phone 7 applications. The back button is supposed to only be used for navigating backwards through the application's page stack, and then to leave the application to navigate backwards through the application stack. To implement any other behavior would be counter-intuitive and is also highly likely to fail certification.

How to resolve communication between my WPF application and a hosted IExplorer?

For a rather large project i have to figure out how (if possible) to resolve this problem. I have a full screen WPF application doing a slideshow - following an interval of e.g. 20 secs per slide. Now I have to investigate into the possibility of replacing the slideshow with a URL instead and have the user navigate the slides instead of changing slides every 10 seconds. The setup is like this:
First the timed slideshow will run, e.g. 5 slides
I show my web page and lets the user interact with the website (navigating)
When the user "Does something (this is the problem)" the website is removed from "slide" and the original slideshow is resumed
The container being shown is a WPF UserControl with an event that allows it to change to the next slide (call a Next() method). The IExporer is hosted within this control.
The problem im facing is this: how do i communicate from the website that my hosting application has to call the NExt() method?
The IExplorer showing the website is hosted within my WPF UserControl. Is there any way i can access some kind of event or anything else to help me determine if a particular page or a particular link has been pressed??
WebServices, files on disc, you name it, im ready to try anything :-)
Any advice or possible solution is appreciated.
If you use the WebBrowser control in your WPF application, you can call into C# classes using javascript from your html. For example, let's say you have a class similar to the following:
[ComVisible(true)]
public class JavaScriptBackEnd
{
public void onclick(string s)
{
MessageBox.Show(s);
}
}
Then initialize the WebBrowser control with the following code:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
webBrowser1.ObjectForScripting = new JavaScriptBackEnd();
webBrowser1.Navigate(new Uri(#"HTMLPage1.htm"));
}
From HTMLPage1.htm you can now call the JavaScriptBackEnd.onclick method with the following javascript:
function testclick() {
window.external.onclick('blabla');
}

What causes a window to not appear in the taskbar until it's Alt-Tabbed to in Vista?

When our app is started programatically (either through custom action in MSI installer or when starting a new instance) in Windows Vista (also happens in Windows 7 Beta) it won't appear in the taskbar and isn't focused. Alt-tabbing to it will make it appear in the taskbar properly and stay there.
What causes this? I've seen this in some other apps before as well, but not sure why. Out app is .NET WinForms app. Never see this happen in XP, only Vista and 7
Edit: Well, it seems like the only time this happens reproducibly is when it's run by the installer, I believe there's other times it occurs, but I might just be crazy. The launching code is a bit complex to post because we handle various command line launch parameters and it launches a signin form before actually launching the main app etc.
Has anyone had to deal with this scenario before and worked it out?
Try checking your main application form "Form Border" property.
If it's ToolWindow (Fixed or Sizable), try changing it to FixedDialog for example.
This solved the problem in my case.
The usual reason for this is that your main application window doesn't have the window styles that let Windows know it's a main application window (rather than a tool window or a dialog box). So Windows is having to guess based on how the app was started, etc.
Use Spy++ to complare the window styles (especially extended styles) if your window to that of some other window that doesn't have this problem. Are you missing the WS_EX_APPWINDOW style? Are any other styles/extended styles different from other top level windows?
G.So's answer made me find the solution for my problem, wich was caused by the fact that i had my form sizable from launch, but set to borderless in the load void.
If anyone is interested in how i managed to keep the switch to borderless and have it pop up as it should in the taskbar without any dirty hacks.. here it is..
Make a new event from the form on the form's "Shown" event, and put your line of code for switching to borderless in here. Problem solved :)
private void Form1_Shown(object sender, EventArgs e)
{
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
}
and for the lazy ones ;) >>>>
this.Shown += new EventHandler(Form1_Shown);
Thanks again G.So for clearing up what could cause this in the first place.
I stuggled with this issue as well, and found like a previous commenter said, you cannot have anything in the form's Load() event that changes that FormBorderStyle property. Move anything that changes it to the Shown() event.
Well, one solution is to use a hack like this. That's really not what it's for.
Usually the decision of whether a window will be in the taskbar or not is based on the border styles it uses. The article I linked to provides a bit more detail. The article's comment about the window having an owner or not is quite possible highly relevant to your issue, since the window might somehow be getting a different owner when launched by the installer.
That article is in VB but it's all based around API calls so the info it provides is pretty language independent.
Never see this happen in XP, only Vista and 7
Maybe it's a bug in Vista...?
What happens if you call SetForegroundWindow() (or equivalent in .Net)?
Edit
I did of course mean "BringWindowToTop()".
Or do both.
We had this same problem and fixed it by setting the form property showintaskbar property to true.
Weird that all windows os's dont run apps in the same way!
In our situation, this was tracked down to the form's text property being changed within the Load event.
After putting this inside a BeginInvoke, this odd behaviour no longer happened.
Hope this helps anyone else.
Example
private void Form_Load(object sender, EventArgs e)
{
...
...
...
// this needs to be inside a BeginInvoke otherwise it messes with the taskbar visibility
this.BeginInvoke(new Action(() =>
{
this.Text = "Something new";
}));
...
...
...
}
We encountered the same issue, also in Windows 8. Sometimes the form was receiving correctly the focus, but say just ~30% of the time.
We tried different solutions, but actually the one that worked was the following:
private void OnFormShown(object sender, EventArgs e)
{
// Tell Windows that the Form is a main application window
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
// Even if true, enforce the fact that we will the application on the taskbar
this.ShowInTaskbar = true;
// Put the window to the front and than back
this.BringToFront();
this.TopMost = true;
this.TopMost = false;
// 'Steal' the focus.
this.Activate();
}
Moreover, we ensure also not to set the title of the form during the Load event.

Resources