Tag Archives: Windows Phone

Microsoft Dev Camps – Free Events

Got this E-Mail. Looks like an interesting addition to the Windows 8 Developer Camps I mentioned earlier.

Tagged ,

BindableApplicationBar for Windows Phone – Now On NuGet

With some help from Shawn Oster – I had the BindableApplicationBar published on NuGet. Now there is no need to search for sources or assemblies on CodePlex if you need to quickly create an MVVM-friendly ApplicationBar. Just right-click on your project and select “Manage NuGet Packages…”

image

Then search for appbar, install it and voila! You can now use the BindableApplicationBar.

Continue reading

Tagged , , , , , , ,

Another XamlParseException – “Unknown parser error: Scanner 2147500037”

Yesterday I got one of those XamlParseExceptions that do not seem to make sense. It happened after I moved most of the code from my Windows Phone application to a class library. In fact the only things I left in the application project were the App class, the Properties folder and some resources that differentiate different applications that share the library. If you want to do something similar – you can have your MainPage class defined in a library and just need to update the WMAppManifest.xml to point at its new location, eg: NavigationPage=”MyClassLibrary;component/Pages/MainPage.xaml”.

Everything worked fine except for this bit:

<i:Interaction.Triggers>
    <ic:PropertyChangedTrigger
        Binding="{Binding PageNumber}">
        <im:ControlStoryboardAction
            ControlStoryboardOption="Play">
            <im:ControlStoryboardAction.Storyboard>
                <Storyboard>
                    <DoubleAnimation ...

It kept throwing an exception:

Continue reading

Tagged , , ,

Vibration Behaviors for Windows Phone – Part 1

So I got my wife an HTC Titan for Christmas and I loved the way it vibrates compared to my Focus. It just feels nice with much lower frequency, while the vibrations on the Focus are a bit like an electric shock. This got me thinking that it would be nice to have the same sort of haptic feedback you get on the 3 hardware buttons on the regular Silverlight buttons. While you could just handle the touch events on every button you choose – it is a lot of code that just gets duplicated all over your app and it is hard to update it globally – e.g. if you want to allow the user to switch it off everywhere or automatically preconfigure it when the app first runs based on the device used. The best solution for it seems to be to create a Behavior that you can easily attach to any button, so that is what I had set off to create.

Continue reading

Tagged , , , ,

ProgressBar and PerformanceProgressBar performance issues with IsIndeterminate = true

Abstract

The gist of this post is that if you use the ProgressBar that comes out of the box with the Windows Phone tools or use the PerformanceProgressBar that comes in the Silverlight Toolkit – you should always set its IsIndeterminate property back to false when you are done displaying it to not use up the CPU and drain the battery.

If you are using an older version of the Silverlight Toolkit – you should update to the latest one, because some of the older ones have a bug that will cause the PerformanceProgressBar to use up the CPU cycles even once you switch IsIndeterminate back to false.

Ideally – you should just use the non-Silverlight-rendered, OS-managed ProgressIndicator like this:

<shell:SystemTray.ProgressIndicator>
    <shell:ProgressIndicator
        IsVisible="{Binding IsWaitingForAnOperationToComplete}"
        IsIndeterminate="True" />
</shell:SystemTray.ProgressIndicator> 

Continue reading

Tagged , , , , ,

BindableApplicationBar RC1 + Windows Phone Prism Application Template

Today marks the RC1 release of the BindableApplicationBar. I have spent some time today to do some StyleCop and documentation cleanup and it seems ready. You can grab a zip file with the binary directly from here.

Another part of what I have been working on today is a Windows Phone application template. I have spent too many times working on boilerplate code and cleaning up the default Windows Phone Application template and decided to create something that will get me up to speed faster every time I want to create a phone app. It is called Windows Phone Prism Application and is available as a Visual Studio project template here.

Continue reading

Tagged , , , , , , , , , , , ,

Good Vibrations on Windows Phone

I thought I’d do something foolish today and decided to play with a Windows Phone API I never used before – the VibrateController. How about playing back a rhythm? I coded up a very simple API to play back sequences of vibrations. You just build a VibrationSequence object with a list of Vibrations that specify vibration duration and a delay between the vibration start and the next vibration.

This is the code that plays it back:

var seq = new VibrationSequence(
    new Vibration(250, 500), 
    new Vibration(250, 1250), 
    new Vibration(200, 250), 
    new Vibration(250, 500), 
    new Vibration(250, 1500));
Play(seq);

And here is the VibrationSequence API:

Continue reading

Tagged , , ,

The quest for a Bindable ApplicationBar – Part 3

This is it – for now at least. The BindableApplicationBar meets all the original requirements and while I found some new ones that might be achievable – it might already be in many ways the richest solution to the problem.

DataContext Changes

Continue reading

Tagged , , , , , , , , ,

Using a UserControl in a Windows Phone app instead of a PhoneApplicationPage

Saw a weird problem today – an app would break when navigating to a certain page if it was not running under the debugger. Then I found it was actually navigating forward out of the application and to the Windows Phone home screen and if you tapped the back button – it would return back to the application. I first thought it had something to do with the WebBrowser control that was used inside of it and the fact that the page control was defined in a class library and not the application assembly, but it turned out to be a dead end. Well, what it did turn out is what the post title says – a UserControl was used instead of a PhoneApplicationPage. A navigation request to that control worked, but unless the app was running with a debugger attached – after a few seconds after navigating to that control it would navigate out of the app. After switching it back to be a PhoneApplicationPage – everything just started working!

It reminded me of another common problem with a stack overflow exception just killing an app with no feedback to the user, even when running under the debugger. A StackOverflowException exists, but can’t be caught – an app just immediately exits when it occurs, so be warned! 🙂

Tagged ,

Debugging visual tree/layout issues in Silverlight and on Windows Phone

Many times, especially when you are doing dynamic layouts, dealing with bindings and DataTemplates – you start scratching your head trying to figure out why your control is not showing up where you want it to show, how to fix it or simply what are the coordinates of some point. You can look through your code, but sometimes the problem is not in your code or it just is not clear.

In such situations it often helps to debug the visual tree of the application and you can do it by browsing the object tree in Visual Studio, but it is sometimes quite laborious since you would usually have to call VisualTreeHelper.GetParent many times before you get to where the problem lies – if you do not get confused on the way and give up. In WPF – I used to use Snoop or Mole. In Silverlight – I did not hear of such tool (I just found about Silverlight Spy today – but it is not free if you want to do anything with Windows Phone). To help solve it I used to write or copy&paste a small attached dependency property that makes the VisualTreeHelper.GetParent calls for me and outputs the interesting properties when a control gets loaded. Today I finally decided to clean it up a bit, make it better and share it with you, so here it is.

Download the sample project here

http://dl.dropbox.com/u/1192076/VisualTreeDebugger.zip

This is just a Windows Phone (Mango) panorama project straight from the template with my VisualTreeDebugger class added and two breakpoint properties defined on some TextBlocks. One will break each time the DataTemplate that includes the TextBlock is applied and the TextBlock loaded, the other one – when you tap on one of the TextBlocks.

How do I use it?

Simply add the VisualTreeDebugger class to your own project, spacify the xmlns reference in XAML and either set VisualTreeDebugger.BreakOnLoaded="True" on your control to have the debugger break when the control first loads or VisualTreeDebugger.BreakOnTap="True" to break when you tap that control. Then just run it from your Visual Studio with debugger attached (F5).

<!--Panorama control-->
<controls:Panorama
    Title="my application">
    <controls:Panorama.Background>
        <ImageBrush
            ImageSource="PanoramaBackground.png" />
    </controls:Panorama.Background>

    <!--Panorama item one-->
    <controls:PanoramaItem
        Header="first item">
        <!--Double line list with text wrapping-->
        <ListBox
            Margin="0,0,-12,0"
            ItemsSource="{Binding Items}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel
                        xmlns:local="clr-namespace:VisualTreeDebugger"
                        Margin="0,0,0,17"
                        Width="432"
                        Height="78">
                        <TextBlock
                            local:VisualTreeDebugger.BreakOnTap="True"
                            Text="{Binding LineOne}"
                            TextWrapping="Wrap"
                            Style="{StaticResource PhoneTextExtraLargeStyle}" />
                        <TextBlock
                            local:VisualTreeDebugger.BreakOnLoaded="True"
                            Text="{Binding LineTwo}"
                            TextWrapping="Wrap"
                            Margin="12,-6,12,0"
                            Style="{StaticResource PhoneTextSubtleStyle}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </controls:PanoramaItem>
</controls:Panorama>

 

What do I get

You get a “path” field which is a list of all dependency objects between your debugged element and the visual tree root. It makes it easy to quickly get access to any of those objects to inspect their properties, when you debug it.

image

image

In the Output/Debug (Ctrl+W, O) window for each of these elements – you get a trace of selected layout properties that may affect the layout, including type, name, actual dimensions and position, logical properties like Width, Height, alignments, Margin and Padding, DataContext and brush information to sweeten the deal.

path[22] is Control: Microsoft.Phone.Controls.Panorama():
    ActualWidth=480
    ActualHeight=800
    Position – X=0, Y=0, Right=480, Bottom=800
    DataContext: VisualTreeDebugger.MainViewModel HashCode: 74304488
    Width=NaN
    Height=NaN
    HorizontalAlignment=Stretch
    VerticalAlignment=Stretch
    Margins=0,0,0,0
    Background=ImageBrush: System.Windows.Media.Imaging.BitmapImage, UriSource: PanoramaBackground.png
    Foreground=SolidColorBrush: #FFFFFFFF

How does it help?

You can find that control somewhere in the dozens of elements of your visual tree that has the alignment or margins set incorrectly or screen position of some invisible panel, find the actual dimensions of the element you need to fill with an image, see which element sets the background for all its contents or simply learn about the structure of the UI. It is easy to use and modify.

Why should I care about this project?

On Windows Phone – rather than coding it yourself – the only other option for debugging visual trees I found was to pay for Silverlight Spy.

With the source code – you can easily add more details that you think might be missing or simply browse the Visual Studio “Watch” window to find them.

Full Source Code of VisualTreeDebugger for quick copy & paste

#if DEBUG
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace VisualTreeDebugger
{
    /// <summary>
    /// The class contains an BreakOnLoaded property that
    /// allows to debug a visual tree from the control
    /// it was applied to up to the visual tree root.
    /// </summary>
    /// <remarks>
    /// Just put a breakpoint in ControlLoaded()
    /// and set VisualTreeDebugger.BreakOnLoaded="True"
    /// on any FrameworkElement/Control.
    /// <para/>
    /// Set BreakOnLoaded if you want to put the breakpoint yourself.
    /// <para/>
    /// DebugVisualTree method has a local path variable
    /// that contains a list of all elements from the visual tree root
    /// up to the debugged control.
    /// <para/>
    /// Debug Output window contains common visual tree layout properties
    /// helpful in debugging layout issues.
    /// </remarks>
    public class VisualTreeDebugger
    {
        #region BreakOnLoaded
        /// <summary>
        /// BreakOnLoaded BreakOnLoaded Dependency Property
        /// </summary>
        public static readonly DependencyProperty BreakOnLoadedProperty =
            DependencyProperty.RegisterAttached(
            "BreakOnLoaded",
            typeof(bool),
            typeof(VisualTreeDebugger),
            new PropertyMetadata(false, OnBreakOnLoadedChanged));

        /// <summary>
        /// Gets the BreakOnLoaded property. This dependency property 
        /// indicates whether the debugger should BreakOnLoaded when control is loaded.
        /// </summary>
        public static bool GetBreakOnLoaded(DependencyObject d)
        {
            return (bool)d.GetValue(BreakOnLoadedProperty);
        }

        /// <summary>
        /// Sets the BreakOnLoaded property. This dependency property 
        /// indicates whether the debugger should BreakOnLoaded when control is loaded.
        /// </summary>
        public static void SetBreakOnLoaded(DependencyObject d, bool value)
        {
            d.SetValue(BreakOnLoadedProperty, value);
        }

        /// <summary>
        /// Handles changes to the BreakOnLoaded property.
        /// </summary>
        private static void OnBreakOnLoadedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue)
            {
                ((FrameworkElement)d).Loaded += ControlLoaded;
            }
            else
            {
                ((FrameworkElement)d).Loaded -= ControlLoaded;
            }
        }
        #endregion

        #region BreakOnTap
        /// <summary>
        /// BreakOnTap Attached Dependency Property
        /// </summary>
        public static readonly DependencyProperty BreakOnTapProperty =
            DependencyProperty.RegisterAttached(
                "BreakOnTap",
                typeof(bool),
                typeof(VisualTreeDebugger),
                new PropertyMetadata(false, OnBreakOnTapChanged));

        /// <summary>
        /// Gets the BreakOnTap property. This dependency property 
        /// indicates whether the attached debugger should break when
        /// the FrameworkElement on which this property is set is tapped.
        /// </summary>
        public static bool GetBreakOnTap(DependencyObject d)
        {
            return (bool)d.GetValue(BreakOnTapProperty);
        }

        /// <summary>
        /// Sets the BreakOnTap property. This dependency property 
        /// indicates whether the attached debugger should break when
        /// the FrameworkElement on which this property is set is tapped.
        /// </summary>
        public static void SetBreakOnTap(DependencyObject d, bool value)
        {
            d.SetValue(BreakOnTapProperty, value);
        }

        /// <summary>
        /// Handles changes to the BreakOnTap property.
        /// </summary>
        private static void OnBreakOnTapChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var frameworkElement = d as FrameworkElement;

            Debug.Assert(frameworkElement != null, "BreakOnTapProperty should only be set on FrameworkElements.");

            if ((bool)e.NewValue)
            {
                ((FrameworkElement)d).Tap += ControlTapped;
            }
            else
            {
                ((FrameworkElement)d).Tap -= ControlTapped;
            }
        }
        #endregion

        /// <summary>
        /// Occurs when the control this behavior is BreakOnLoaded to gets loaded.
        /// Put a breakpoint in here and set ControlDebugOnLoaded.BreakOnLoaded="True"
        /// on any control to debug its visual tree.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private static void ControlLoaded(object sender, RoutedEventArgs e)
        {
            var startElement = (DependencyObject)sender;
            DebugVisualTree(startElement);
        }

        static void ControlTapped(object sender, GestureEventArgs e)
        {
            var startElement = (DependencyObject)sender;
            DebugVisualTree(startElement);
        }

        #region DebugVisualTree()
        public static void DebugVisualTree(DependencyObject startElement)
        {
            var path = new List<DependencyObject>();
            var dob = startElement;

            while (dob != null)
            {
                path.Add(dob);
                dob = VisualTreeHelper.GetParent(dob);
            }

            for (int i = path.Count - 1; i >= 0; i--)
            {
                TraceDependencyObject(path[i], i);
            }

            // Put breakpoint here
            Debug.WriteLine(
                string.Format("Watch path[0] to path[{0}]",
                path.Count - 1));

            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }
        }
        #endregion

        #region TraceDependencyObject()
        private static void TraceDependencyObject(DependencyObject dob, int i)
        {
            var frameworkElement = dob as FrameworkElement;

            if (frameworkElement == null)
            {
                Debug.WriteLine(
                    "path[{0}] is Dependency Object: {1}",
                    i,
                    dob.GetType());
            }
            else
            {
                var c = frameworkElement as Control;
                var cc = frameworkElement as ContentControl;
                var panel = frameworkElement as Panel;
                var parentGrid = frameworkElement.Parent as Grid;

                Debug.WriteLine(
                    "path[{0}] is Control: {1}({2}):",
                    i,
                    frameworkElement.GetType(),
                    frameworkElement.Name ?? "<unnamed>");

                // Actual layout information
                Debug.WriteLine("\tActualWidth={0}\r\n\tActualHeight={1}", frameworkElement.ActualWidth, frameworkElement.ActualHeight);
                var pos = frameworkElement.TransformToVisual(Application.Current.RootVisual).Transform(new Point());
                var pos2 = frameworkElement.TransformToVisual(Application.Current.RootVisual).Transform(new Point(frameworkElement.ActualWidth, frameworkElement.ActualHeight));
                Debug.WriteLine("\tPosition - X={0}, Y={1}, Right={2}, Bottom={3}",
                    pos.X,
                    pos.Y,
                    pos2.X,
                    pos2.Y);

                // DataContext often turns out to be a surprise
                Debug.WriteLine("\tDataContext: {0} {1}", frameworkElement.DataContext, frameworkElement.DataContext != null ? "HashCode: " + frameworkElement.DataContext.GetHashCode() : "");

                // List common layout properties
                Debug.WriteLine("\tWidth={0}\r\n\tHeight={1}", frameworkElement.Width, frameworkElement.Height);
                Debug.WriteLine("\tHorizontalAlignment={0}\r\n\tVerticalAlignment={1}", frameworkElement.HorizontalAlignment, frameworkElement.VerticalAlignment);

                if (cc != null)
                {
                    Debug.WriteLine(
                        "\tHorizontalContentAlignment={0}\r\n\tVerticalContentAlignment={1}",
                        cc.HorizontalContentAlignment,
                        cc.VerticalContentAlignment);
                }

                Debug.WriteLine("\tMargins={0}", frameworkElement.Margin);

                if (cc != null)
                {
                    Debug.WriteLine("\tPadding={0}", cc.Padding);
                }

                if (panel != null)
                {
                    Debug.WriteLine("\tBackground={0}", panel.Background);
                }
                else if (c != null)
                {
                    Debug.WriteLine("\tBackground={0}", BrushToString(c.Background));
                    Debug.WriteLine("\tForeground={0}", BrushToString(c.Foreground));
                }

                if (parentGrid != null)
                {

                    var col = Grid.GetColumn(frameworkElement);
                    var row = Grid.GetRow(frameworkElement);

                    if (parentGrid.ColumnDefinitions.Count != 0 || col != 0)
                    {
                        Debug.Assert(
                            col < parentGrid.ColumnDefinitions.Count,
                            string.Format("Column {0} not defined on the parent Grid!", col));
                        Debug.WriteLine(
                            "\tColumn: {0} ({1})",
                            col,
                            parentGrid.ColumnDefinitions[col].Width);
                    }

                    if (parentGrid.RowDefinitions.Count != 0 || row != 0)
                    {
                        Debug.Assert(
                            row < parentGrid.RowDefinitions.Count,
                            string.Format("Row {0} not defined on the parent Grid!", row));
                        Debug.WriteLine(
                            "\tRow: {0} ({1})",
                            row,
                            parentGrid.RowDefinitions[col].Height);
                    }
                }

                if (frameworkElement.Parent is Canvas)
                {
                    var x = Canvas.GetLeft(frameworkElement);
                    var y = Canvas.GetTop(frameworkElement);
                    var zIndex = Canvas.GetZIndex(frameworkElement);

                    Debug.WriteLine("\tCanvas - X={0}, Y={1}, ZIndex={2}", x, y, zIndex);
                }
            }
        }
        #endregion

        #region BrushToString()
        private static string BrushToString(Brush brush)
        {
            if (brush == null)
                return "";

            var solidColorBrush = brush as SolidColorBrush;

            if (solidColorBrush != null)
            {
                return string.Format("SolidColorBrush: {0}", solidColorBrush.Color);
            }

            var imageBrush = brush as ImageBrush;

            if (imageBrush != null)
            {
                var bi = imageBrush.ImageSource as BitmapImage;

                if (bi != null)
                {
                    return string.Format(
                        "ImageBrush: {0}, UriSource: {1}",
                        bi,
                        bi.UriSource);
                }

                return string.Format("ImageBrush: {0}", imageBrush.ImageSource);
            }

            return brush.ToString();
        }
        #endregion
    }
}
#endif
Tagged , , , , ,