Re-imagining the behavior to show the Windows Phone 7 camera as background
This blog turns out not only to be a collection of how-to samples but also a record of my evolution as a Windows Phone 7 developer. At the end of my previous post, Safe event detachment base class for Windows Phone 7 behaviors, I promised a usage example and I decided to re-implement the behavior to show the Windows Phone 7 camera as background using the SafeBehavior as a base class. This makes the code considerable easier.
The base setup of the re-implemented behavior is pretty simple:
using System.Windows.Controls; using System.Windows.Media; using System.Windows.Navigation; using Microsoft.Devices; using Microsoft.Phone.Controls; namespace Wp7nl.Behaviors { /// <summary> /// A behavior that shows a camera view on the background of a panel /// </summary> public class CameraViewBackgroundBehavior : SafeBehavior<Panel> { private PhotoCamera camera; private VideoBrush backgroundBrush; public CameraViewBackgroundBehavior() { ListenToPageBackEvent = true; } } }
Note this behavior needs to detect the user navigating back to the page – this in necessary because we need to do something with the camera.
In stead of all the song and dance for attaching and detaching events using the snippet I published earlier, it’s now a matter of overriding the OnSetup and OnCleanup methods to initialize the camera:
protected override void OnSetup() { if (camera == null) { camera = new PhotoCamera(); ParentPage.OrientationChanged += ParentPageOrientationChanged; } // Create a video brush with the right parameters backgroundBrush = new VideoBrush { Stretch = Stretch.UniformToFill, AlignmentX = AlignmentX.Left, AlignmentY = AlignmentY.Top }; // Set the video brush to the background of the panel // and and do an initial display AssociatedObject.Background = backgroundBrush; backgroundBrush.SetSource(camera); SetVideoOrientation(ParentPage.Orientation); } protected override void OnCleanup() { ParentPage.OrientationChanged -= ParentPageOrientationChanged; camera.Dispose(); camera = null; }
This behavior also needs to do some action when the user actually navigates back to the page, which you can do by override the OnParentPageNavigated method - in this case, re-initializing the whole behavior
/// <summary> /// Fired whe page navigation happens /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected override void OnParentPageNavigated(object sender, NavigationEventArgs e) { // Re-setup when this page is navigated BACK to if( IsNavigatingBackToBehaviorPage(e)) { if (camera != null) { OnCleanup(); OnSetup(); } } }
The actual implementation of showing the camera background has hardly changed, and is only mentioned here for the sake of completeness:
private void ParentPageOrientationChanged(object sender, OrientationChangedEventArgs e) { SetVideoOrientation(e.Orientation); } /// <summary> /// Sets background video brush parameters based upon page orientation /// </summary> /// <param name="orientation"></param> private void SetVideoOrientation(PageOrientation orientation) { System.Diagnostics.Debug.WriteLine("Switching to {0}", orientation); switch (orientation) { case PageOrientation.PortraitUp: backgroundBrush.Transform = new CompositeTransform { Rotation = 90, TranslateX = 480 }; break; case PageOrientation.LandscapeLeft: backgroundBrush.Transform = null; break; case PageOrientation.LandscapeRight: if (Microsoft.Phone.Shell.SystemTray.IsVisible ) { backgroundBrush.Transform = new CompositeTransform { Rotation = 180, TranslateX = 728, TranslateY = 480 }; } else { backgroundBrush.Transform = new CompositeTransform { Rotation = 180, TranslateX = 800, TranslateY = 480 }; } break; } }
As this post demonstrated, using the SafeBehavior as a base class makes life a lot easier than implementing the whole pattern over and over again, even when using a snippet.
Code is part of the the #wp7nl library on codeplex and can be found here