Tuesday, December 25, 2012

Windows Phone 8 project update fails with "reference cannot be removed from the project because it is always referenced by the compiler"

When using Visual Studio 2012 to upgrade an existing WP7.1 project to WP8 the process failed with the message:

Upgrade to the project could not be completed. This reference cannot be removed from the project because it is always referenced by the compiler.

Followed by:

Upgrade to the project could not be completed. Error HRESULT E_FAIL has been returned from a call to a COM component.

I found the solution in the post Upgrade Windows Phone 7.1 project to Windows Phone 8?

My project was missing the reference to System.Core.dll before attempting the upgrade. The was a reference to mscorlib.dll.

For some unknown reason attempting to add the System.Core reference to the project from Visual Studio didn't work. It would check in the add dialog but wouldn't then be present in the list of references.

In the end I needed to manually add the reference to the project via notepad.

After that the reference appeared as required in Visual Studio and the upgrade to the Windows Phone 8 project succeeded.

Saturday, December 15, 2012

A mock Windows Phone Microsoft.Devices.Sensors.Motion API for emulator support

The Windows Phone 7/8 emulators provide accelerometer support, but not support for the Microsoft.Devices.Sensors.Motion API.

I've created MotionWrapper and MockMotionReading classes that can provide fake data when using the emulator in debug mode. When you switch to a real device or a release build it reverts to an underlying Motion instance.

At this stage the MockMotionReading only varies the pitch, roll, and yaw and then calculates the corresponding RotationMatrix and Quaternion. The Gravity vector is left unchanged.

Ideally I'd like to use the accelerometer data to determine a Gravity vector so it could be varied during testing.

MotionWrapper

/// <summary>
    /// Provides Windows Phone applications information about the device’s orientation and motion.
    /// </summary>
    public class MotionWrapper //: SensorBase<MotionReading> // No public constructors, nice one.
    {
        private Motion motion;

        public event EventHandler<SensorReadingEventArgs<MockMotionReading>> CurrentValueChanged;

        #region Properties
        /// <summary>
        /// Gets or sets the preferred time between Microsoft.Devices.Sensors.SensorBase<TSensorReading>.CurrentValueChanged events.
        /// </summary>
        public virtual TimeSpan TimeBetweenUpdates
        {
            get
            {
                return motion.TimeBetweenUpdates;
            }
            set
            {
                motion.TimeBetweenUpdates = value;
            }
        }

        /// <summary>
        /// Gets or sets whether the device on which the application is running supports the sensors required by the Microsoft.Devices.Sensors.Motion class.
        /// </summary>
        public static bool IsSupported
        {
            get
            {
#if(DEBUG)
                return true;
#else
                return Motion.IsSupported;
#endif

            }
        }
        #endregion

        #region Constructors
        protected MotionWrapper()
        {
        }

        protected MotionWrapper(Motion motion)
        {
            this.motion = motion;
            this.motion.CurrentValueChanged += motion_CurrentValueChanged;
        }
        #endregion

        /// <summary>
        /// Get an instance of the MotionWrappper that supports the Motion API
        /// </summary>
        /// <returns></returns>
        public static MotionWrapper Instance()
        {
#if(DEBUG)
            if (!Motion.IsSupported)
            {
                return new MockMotionWrapper();
            }
#endif
            return new MotionWrapper(new Motion());
        }

        /// <summary>
        /// The value from the underlying Motion API has changed. Relay it on within a MockMotionReading.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void motion_CurrentValueChanged(object sender, SensorReadingEventArgs<MotionReading> e)
        {
            var f = new SensorReadingEventArgs<MockMotionReading>();
            f.SensorReading = new MockMotionReading(e.SensorReading);
   RaiseValueChangedEvent(sender, f);
        }

        protected void RaiseValueChangedEvent(object sender, SensorReadingEventArgs<MockMotionReading> e)
        {
            if (CurrentValueChanged != null)
            {
                CurrentValueChanged(this, e);
            }
        }

        /// <summary>
        /// Starts acquisition of data from the sensor.
        /// </summary>
        public virtual void Start()
        {
            motion.Start();
        }

        /// <summary>
        /// Stops acquisition of data from the sensor.
        /// </summary>
        public virtual void Stop()
        {
            motion.Stop();
        }
    }

MockMotionWrapper

/// <summary>
    /// Provides Windows Phone applications mock information about the device’s orientation and motion.
    /// </summary>
    public class MockMotionWrapper : MotionWrapper
    {
        /// <summary>
        /// Use a timer to trigger simulated data updates.
        /// </summary>
        private DispatcherTimer timer;

        private MockMotionReading lastCompassReading = new MockMotionReading(true);

        #region Properties
        /// <summary>
        /// Gets or sets the preferred time between Microsoft.Devices.Sensors.SensorBase<TSensorReading>.CurrentValueChanged events.
        /// </summary>
        public override TimeSpan TimeBetweenUpdates
        {
            get
            {
                return timer.Interval;
            }
            set
            {
                timer.Interval = value;
            }
        }
        #endregion

        #region Constructors
        public MockMotionWrapper()
        {
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(30);
            timer.Tick += new EventHandler(timer_Tick);
        }
        #endregion

        void timer_Tick(object sender, EventArgs e)
        {
            var reading = new Microsoft.Devices.Sensors.SensorReadingEventArgs<MockMotionReading>();
            lastCompassReading = new MockMotionReading(lastCompassReading);
            reading.SensorReading = lastCompassReading;

            //if (lastCompassReading.HeadingAccuracy > 20)
            //{
            //    RaiseValueChangedEvent(this, new CalibrationEventArgs());
            //}

            RaiseValueChangedEvent(this, reading);
        }

        /// <summary>
        /// Starts acquisition of data from the sensor.
        /// </summary>
        public override void Start()
        {
            timer.Start();
        }

        /// <summary>
        /// Stops acquisition of data from the sensor.
        /// </summary>
        public override void Stop()
        {
            timer.Stop();
        }

    }

MockMotionReading

//Microsoft.Devices.Sensors.MotionReading
    /// <summary>
    /// Contains information about the orientation and movement of the device.
    /// </summary>
    public struct MockMotionReading : Microsoft.Devices.Sensors.ISensorReading
    {
        public static bool RequiresCalibration = false;

        #region Properties
        /// <summary>
        /// Gets the attitude (yaw, pitch, and roll) of the device, in radians.
        /// </summary>
        public MockAttitudeReading Attitude { get; internal set; }

        /// <summary>
        ///  Gets the linear acceleration of the device, in gravitational units.
        /// </summary>
        public Vector3 DeviceAcceleration { get; internal set; }

        /// <summary>
        /// Gets the rotational velocity of the device, in radians per second.
        /// </summary>
        public Vector3 DeviceRotationRate { get; internal set; }

        /// <summary>
        /// Gets the gravity vector associated with the Microsoft.Devices.Sensors.MotionReading.
        /// </summary>
        public Vector3 Gravity { get; internal set; }

        /// <summary>
        /// Gets a timestamp indicating the time at which the accelerometer reading was
        ///     taken. This can be used to correlate readings across sensors and provide
        ///     additional input to algorithms that process raw sensor data.
        /// </summary>
        public DateTimeOffset Timestamp { get; internal set; }
        #endregion

        #region Constructors

        /// <summary>
        /// Initialize an instance from an actual MotionReading
        /// </summary>
        /// <param name="cr"></param>
        public MockMotionReading(MotionReading cr)
            : this()
        {
            this.Attitude = new MockAttitudeReading(cr.Attitude);
            this.DeviceAcceleration = cr.DeviceAcceleration;
            this.DeviceRotationRate = cr.DeviceRotationRate;
            this.Gravity = cr.Gravity;
            this.Timestamp = cr.Timestamp;
        }

        /// <summary>
        /// Create an instance initialized with testing data
        /// </summary>
        /// <param name="test"></param>
        public MockMotionReading(bool test) 
            : this()
        {
            float pitch = 0.01f;
            float roll = 0.02f;
            float yaw = 0.03f;

            this.Attitude = new MockAttitudeReading()
            {
                Pitch = pitch,
                Roll = roll,
                Yaw = yaw,
                RotationMatrix = Matrix.CreateFromYawPitchRoll(yaw, pitch, roll),  
                Quaternion = Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll), 

                Timestamp = DateTimeOffset.Now
            };

            // TODO: pull data from the Accelerometer
            this.Gravity = new Vector3(0, 0, 1f);
        }

        /// <summary>
        /// Create a new mock instance based on the previous mock instance
        /// </summary>
        /// <param name="lastCompassReading"></param>
        public MockMotionReading(MockMotionReading lastCompassReading)
            : this()
        {
            // Adjust the pitch, roll, and yaw as required.

            // -90 to 90 deg
            float pitchDegrees = MathHelper.ToDegrees(lastCompassReading.Attitude.Pitch) - 0.5f;
            //pitchDegrees = ((pitchDegrees + 90) % 180) - 90;

            // -90 to 90 deg
            float rollDegrees = MathHelper.ToDegrees(lastCompassReading.Attitude.Roll);
            //rollDegrees = ((rollDegrees + 90) % 180) - 90;

            // 0 to 360 deg
            float yawDegrees = MathHelper.ToDegrees(lastCompassReading.Attitude.Yaw) + 0.5f;
            //yawDegrees = yawDegrees % 360;

            float pitch = MathHelper.ToRadians(pitchDegrees);
            float roll = MathHelper.ToRadians(rollDegrees);
            float yaw = MathHelper.ToRadians(yawDegrees);

            this.Attitude = new MockAttitudeReading()
            {
                Pitch = pitch,
                Roll = roll,
                Yaw = yaw,
                RotationMatrix = Matrix.CreateFromYawPitchRoll(yaw, pitch, roll),
                Quaternion = Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll),
                
                Timestamp = DateTimeOffset.Now
            };
            
            this.DeviceAcceleration = lastCompassReading.DeviceAcceleration;
            this.DeviceRotationRate = lastCompassReading.DeviceRotationRate;
            this.Gravity = lastCompassReading.Gravity;
            Timestamp = DateTime.Now;

        }
        #endregion



    }

MockAttitudeReading

public struct MockAttitudeReading : ISensorReading
    {
        public MockAttitudeReading(AttitudeReading attitudeReading) : this()
        {
            Pitch = attitudeReading.Pitch;
            Quaternion = attitudeReading.Quaternion;
            Roll = attitudeReading.Roll;
            RotationMatrix = attitudeReading.RotationMatrix;
            Timestamp = attitudeReading.Timestamp;
            Yaw = attitudeReading.Yaw;
        }

        /// <summary>
        /// Gets the pitch of the attitude reading in radians.
        /// </summary>
        public float Pitch { get; set; }
        
        /// <summary>
        /// Gets the quaternion representation of the attitude reading.
        /// </summary>
        public Quaternion Quaternion { get; set; }
        
        /// <summary>
        /// Gets the roll of the attitude reading in radians.
        /// </summary>
        public float Roll { get; set; }
        
        /// <summary>
        /// Gets the matrix representation of the attitude reading.
        /// </summary>
        public Matrix RotationMatrix { get; set; }

        /// <summary>
        /// Gets a timestamp indicating the time at which the accelerometer reading was
        ///     taken. This can be used to correlate readings across sensors and provide
        ///     additional input to algorithms that process raw sensor data.
        /// </summary>
        public DateTimeOffset Timestamp { get; set; }
        
        /// <summary>
        /// Gets the yaw of the attitude reading in radians.
        /// </summary>
        public float Yaw { get; set; }
    }

See Also:

Wednesday, December 12, 2012

Days between two DateTime values excluding weekends

Given two DateTime values in Apex, how many weekdays are there between the two?

Getting the total number of days is straight forward using Date.daysBetween(). Excluding the weekends requires a bit more work.

One possible solution is to just loop through all the dates between the two values and count any that aren't Saturday or Sunday. It's a bit crude and will be expensive if the dates are far apart. It should however work through pure brute force.

    public static Integer daysBetweenExcludingWeekends(Datetime startDate, Datetime endDate) {
        Integer i = 0;

        while (startDate < endDate) {
            if (startDate.format('EEE') != 'Sat' && startDate.format('EEE') != 'Sun') {
                i = i + 1;
            }
            startDate = startDate.addDays(1);
        }
          
        return i;
    }

See also:

Friday, December 7, 2012

Applying CSS to a Visualforce apex:selectOption

I had a customer requirement to put some CSS formatted labels on some radio buttons in a Visualforce page. The markup was already using an <apex:selectOption> within a <apex:selectRadio>. I didn't want to revert to raw HTML controls as there was a <apex:actionSupport> already in use.

Using the style or styleClass to apply the CSS to the selectOption didn't work as they were deprecated in Salesforce API version 17.0.

Instead I created a property in the controller that returned the required HTML markup and set itemEscaped="false" on the selectOption.

E.g.:

Page:

    <apex:selectRadio layout="pageDirection" value="{!controllerflag}" rendered="{!(!addingNew)}">
        <apex:actionSupport action="{!getData}" status="addItem" event="onclick" rerender="somePageBlock">
            <apex:param name="selectedId" value="{!elementId}"/>
        </apex:actionSupport>
        <apex:selectOption itemLabel="{!radioSelectLabel}" itemEscaped="false" itemValue="true" >
        </apex:selectOption>
    </apex:selectRadio>

Controller:

    public string radioSelectLabel {
        get {
            if (hasBeenCancelled) {
                return '<span style="color:red;">(Cancelled)</span>';
            }
            return 'Available';
        }
    }

Friday, November 30, 2012

Windows Phone 8 Emulator issues in Visual Studio 2012

I haven't had much luck to date getting up and running with the WP8 SDK for Visual Studio 2012. When I attempt to start the emulator I get the message:

The connection to the virtual machine has been lost. The virtual machine may have been turned off by another application. The Windows Phone Emulator must close.

After this has occurred, attempts to restart the emulator produce the following error:

The Windows Phone Emulator wasn't able to set some properties on the virtual machine:

Couldn't change Memory of the virtual machine: Error code 32775

I have a 64-bit Intel i7 processor with virtualization enabled in the bios. Hyper-V is installed. I have more than enough memory (32 GB).


Solution

I found my specific issue. The VPN software that I had installed was preventing the local VM connection, even when it wasn't actively running. Uninstalling it resolved the issue.

The response from the VPN provider indicated the issue was with the Layered Service Providers:

It seems the problem is with incompatibility of LSPs (Layered Service Providers) - [VPN Name] uses a LSP to redirect traffic as well as Hyper-V software.

See Also:

Salesforce convert Apex integer to long

A quick snippet after I came across the following when modifying some apex:

integer someId = 12345;
aMethodThatTakesALong(Long.valueOf(someId.format()));

Note the transition via an intermediate string to get to the long required by the method.

Usually Apex will implicitly convert an integer to a long if required. E.g.

Integer testInt = 12345;
Long testLong = testInt;
System.assertEquals(12345L, testLong);

In the case of the method parameter above you can either rely on the implicit casting or, where there may be other overrides available, explicitly cast the integer to a long. E.g.

integer someId = 12345;
aMethodThatTakesALong((long)someId);

Tuesday, October 30, 2012

Salesforce - Unable to uninstall package due to page layouts

Uninstalling a package from a Salesforce org failed recently due to references from profiles to page layouts.

Unable to uninstall package
This installed component is referenced by a locally created component. System Administrator
Unable to uninstall package

It is possible to remove this mapping by following the link to the profile and changing the page layout assignments for the affected objects.

Alternatively, I found it quicker to manually remove the page layout and use the replacement screen provided by Salesforce.

App Setup > Customize > Accounts > Page Layouts > Page Layout Name : Del

Then use the page layout replacement screen to reassign any references to a remaining page layout.

Wednesday, October 24, 2012

Changing the Windows Store Market

I recently published an app to the Windows Store and was puzzled why I couldn't find it in the Store to install from other machines.

When I published the app I restricted it to the New Zealand market. Turns out my current Windows 8 language settings were sending me to the wrong store.

  • Go to the Control Panel under the Settings charm.
  • In the Control Panel, click on Clock, Language, and Region.
  • Click on 'Add a language'
  • [Optionally] in the opened Window again click on 'Add a language' to add your language to Windows. (Ignore this step if you already have the required language)
  • Move the language the corresponds to the required store to the top of the list. Making it your primary language.
  • Back at Clock, Language, and Region, click on 'Change location' and select the location from the drop-menu and then click on OK.

Sunday, October 21, 2012

Debugging a WinRT background task

With Windows Phone 7 apps I often used ScheduledActionService.LaunchForTest to make background agents run quickly when debugging so I didn't need to wait 15 minutes before they would fire.

With WinRT you can now trigger the Background Task directly from Visual Studio. To do so:

  • Bring up the Debug Location toolbar. Right click somewhere in an empty toolbar if you can't find it.
  • Trigger the code that registers the background task.
  • Click the dropdown next to suspend and select the class that the background task runs.

See also:

Wednesday, October 17, 2012

DEP0700 : Registration of the app failed. Windows cannot install package

The following error appeared in Visual Studio when trying to run the Bing Maps SDK examples:

Error : DEP0700 : Registration of the app failed. Windows cannot install package 133E2AEE-177A-43F4-BB19-4A6CCA8BD2CA because the package requires architecture ARM, but this computer has architecture x64. (0x80073cf3) PushpinSample

The fix was simple enough. Change the Platform from ARM to x64 in the Configuration Manager.

Tuesday, October 16, 2012

Salesforce Save error: Illegal assignment from Decimal to Long

A very simple type conversion error occurs in Apex when trying to implicitly cast from a Decimal (an arbitrary precision number) to a Long (A 64-bit number that does not include a decimal point).

Save error: Illegal assignment from Decimal to Long

I noticed some inherited code was solving the issue by converting via an intermediate String. Using the dedicated Decimal.longValue() was a bit cleaner.

Decimal testDecimal = 123.0;
Long convertedDecimal = testDecimal; // results in "Illegal assignment from Decimal to Long"

// Conversion via a string works, but is a bit ugly
Long conversionViaString = Long.valueOf(String.valueof(testDecimal));
System.assertEquals(123, conversionViaString);

// Direct conversion using dedicated Decimal method
Long directLongConversion = testDecimal.longValue();
System.assertEquals(123, directLongConversion );

Tuesday, October 9, 2012

Salesforce Save error: Entity is not org-accessible

The following line of Apex attempting to pull the more recent ApexPages Message produced an error I haven't encountered before. What made it particularly confusing was the lack of a line reference in the error.

Message mostRecentMessage = ApexPages.getMessages().get(ApexPages.getMessages().size() - 1);
Save error: Entity is not org-accessible

Changing is as follows resolved the issue (Note the ApexPages.):

ApexPages.Message mostRecentMessage = ApexPages.getMessages().get(ApexPages.getMessages().size()-1);

If you encounter the same error check the most recently changed lines for incorrect class references, such as a spelling mistake, a missing classname or __c suffix.

Tuesday, September 25, 2012

WinRT ArgumentOutOfRangeException "No mapping for the Unicode character exists in the target multi-byte code page" from FileIO.ReadTextAsync()

Problem

The following code to read the text contents of a file in WinRT thru an exception on some txt files and not on others.

var localFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
var file = await localFolder.GetFileAsync("Sample.txt");
var stringContent = await Windows.Storage.FileIO.ReadTextAsync(file);
An exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll but was not handled in user code

WinRT information: No mapping for the Unicode character exists in the target multi-byte code page.

Additional information: No mapping for the Unicode character exists in the target multi-byte code page. (Exception from HRESULT: 0x80070459)

If there is a handler for this exception, the program may be safely continued.

Solution 1 - Remove all the problem characters

The following line in the txt file was causing the issue:

Rangitoto ki te Tonga/D’Urville Island

Changing the to a ' resolved the issue.

In another text file I also needed to change a to -.

Solution 2

Change the file encoding using Visual Studio. When I opened the file it had the encoding: "Western European (Windows) - Codepage 1252"

  1. Open the file in Visual Studio
  2. File > Advanced Save Options... >
  3. Change the encoding to "Unicode (UTF-8 with signature) - Codepage 65001"
  4. Save the file

Wednesday, September 12, 2012

Windows Phone 7 - Compass Bearing

About Compass Bearing for WP7

Shows true north and magnetic compass bearing as reported by the phone. Using your location data the app will also show a calculated true north bearing with independent magnetic declination calculation based on your latitude and longitude.

In vision mode you get an augmented reality compass that can be switched between the phone and app true north readings.

Tapping in the center of the compass dial will toggle between:

  • app true - The bearing for true north calculated using the reported magnetic north bearing and the magnetic declination for your location.
  • magnetic - Magnetic north as reported by the operating system. Theoretically this should point in the same direction as a physical compass would. There are known bugs with Windows Phone 7 handsets that can cause this to point in the wrong direction.
  • phone true - True north as reported by the operating system.

Trial mode is fully functional.

Tips and FAQ

The compass isn't pointing North

There are a number of factors that could cause an incorrect compass bearing.

  1. Calibration
    Within your handset is a magnetometer sensor. This sensor measures the strength of the magnetic field and reports the values via the phones operating system. It needs to be calibrated from time to time to ensure correct operation.
    One way to do this is to move it close to another magnet so that the calibration screen appears. Then move the phone away from the magnet and rotate it around all the axis.

    Hold the device in front of you and sweep it through a figure 8 pattern as shown until the calibration is complete.

    Another option to force calibration is to turn the phone off and then on again.
  2. Interference
    A number of objects may interfere with the magnetometer readings. Try moving away from magnets, other electrical devices (especially speakers), large pieces of metal, etc...
  3. Access to location information
    The Compass bearing app requires access to your location information to correctly determine the magnetic declination for your latitude and longitude.

Still not working?

If the issue still persists, can you please provide me some further details:

  • What is your approximate latitude and longitude or country and city of origin. These don't need to be exact, just sufficient so I can check the magnetic declination for your location.
  • Could you send me a screen capture from Raw Compass Data running on a level surface? There is a dedicated capture button in the bottom right that will save a screenshot to the picture library.

Known Issues

v1.4.0 There is a bug that can cause an exception when starting vision mode. There is currently a fix for this going through certification and it should be available soon.

See also:

Sunday, September 9, 2012

WP7 Application causes the onscreen keyboard to stay on

Setting focus to a TextBox immediately after calling MessageBox.Show() can cause the onscreen keyboard to get stuck on if the user presses the devices start button while the prompt is still displayed.

Once in this state you need to find an application that will display the keyboard so that it can be dismissed normally.

For example, rather than doing something like:

if (string.IsNullOrEmpty(ivm.Name))
{
    MessageBox.Show("Please enter a name");
    // This line will still occur if the user presses the hardware start button while the message box is displayed and will cause the keyboard to appear on the start screen.
    sampleTextBox.Focus();
                
    return;
}

Instead, set the focus before showing the message box so the keyboard can be dismissed by the OS code when the hardware button is pressed.

if (string.IsNullOrEmpty(ivm.Name))
{
    sampleTextBox.Focus();
    MessageBox.Show("Please enter a name");
                
    return;
}

Friday, September 7, 2012

TechEd 2012 Round Up / Summary

I've summarised some of the most interesting/important parts of my TechEd 2011 NZ notes here.


Keynote - Part 1 Part 2

DEV201 What's New in Microsoft Visual Studio 2012

Presenter: Adam Cogan @AdamCogan


DBI201: What's New in Microsoft SQL Server 2012

  • Concat - implicit cast. Null handling.
  • Try_Convert - return null rather than exception is cast fails
  • Parse - Returns the result of the expression, translated to the requested data type.
  • Format - like .NET format [23:00]
  • EOMonth - End of month [25:00]
  • DateFromParts - Build a data from parts
  • Throw [33:40] - rethrow the exception
  • sp_describe_first_result_set - types from the result set [38:00]

APP207: Windows UI Design


DEV301: Asychronous Programming in Visual Studio 2012

Presenter: Ivan Towlson

  • Challenges
    • Code readability - async can break up the logical flow
    • Exception handling - Where did the exception occur.
    • Resource management - placement of using statements, etc...
  • async
    "This method may return before is has finished".
  • await contextual keyword.
    "Return from this method for now*, but resume it again when the following operation has completed"
    * Maybe
  • The await keyword will ultimately strip off the asynchronous Task without blocking the calling thread.
  • Exception handling - Centralized exception handling. Very similar to how the synchronous method would be written. Don't need a separate exception handler.
  • CancellationToken, CancellationTokenSource - OperationCanceledException
  • await Task.WhenAll(downloads); //A task that becomes complete when all of the sub tasks are complete.
  • Inside await
    - Split method into synchronous blocks.
    - Compiler creates glue code for GetAwaiter()
    - Awaiter has a OnCompleted callback, GetResult(), and IsCompleted.
  • await Internally uses StateMachine
  • What async/await Isn't
    • A Way to do parallel processing - Use Parallel LINQ or the TPL
    • A way for multiple concurrent operations to coordinate - Use agents
  • Shifting computations in time
    • Futures (Task) computations in progress who whose results will become available at some point.
    • Delays (Lazy) computations which will be delayed until the results are needed (but performed sync)
      "defer the creation of a large or resource-intensive object or the execution of a resource-intensive task, particularly when such creation or execution might not occur during the lifetime of the program"
    • Promises:
    • Agents: concurrent objects which communicate asynchronously and are internally serial
  • Summary
    • Blocking calls in naughty.
    • async and await allow you to write async/good programs that are as easy to write and to read as sync/bad ones.
  • See also:


    INO101:Microsoft Future Vision


    APP202:The Absolute Beginner's Guide To Building Windows 8 Apps In C# and XAML

    Presenters: Ian Randall @kiwipom and Ben Gracewood @nzben

    • Metro Design Principles
    • Pixel (device independent pixels)
      Sub unit - 5x5 pixels
      1 Unit - 20x20 pixels
    • XAML Spy - HTML DOM browser equivalent for XAML
    • Spacing - 1/2 unit (10 pixels) between similar elements.
    • Font Ramp: Header, Sub Header, Small Sub Header, Body Text
    • Fast and Fluid
      - Motion
      - Responsiveness
      - Get off the UI thread
      - Wait 25 ms when arriving at the page before loading content. Displays initial page faster.
    • Authentically Digital - Avoid skeuomorphism

      "The details and design should focus on function rather than trying to emulate real-world analog versions of things, like the animation of a page turning in an e-book."
    • Use Contracts to integrate with the rest of windows.
      You don't need your own independent settings or Search functions.

    APP201:From Lazy to Metro - A Journey on Windows Phone and Windows 8

    DEV304:Engaging the Realtime Web with SignalR


    SIA201:Hack-Ed: From the Trenches

    Presenters: Andy Prow and Kirk Jackson

    • Back Tracking on a RegEx and consume CPU time. Place time limits on execution.
    • Consider segmenting the authentication system from the core database to protect against SQL injection exposing data.

    APP310: Bring Your Windows 8 and Windows Phone Apps to Life with Push Notifications using Windows Azure

    Presenter Nick Harris @cloudnick

    • Windows Push Notification Service (WNS)
    • Types of tile template variation: Text only, images only or a combination.
    • Badges for tiles
    • Use Toast Templates to inform the user of something important.
      The best toast notifications are personally relevant and time sensitive.
      Don't over use toast notifications.
    • Each tile has a unique Channel URI. Requested by App on each run. URI can change. Typically expires every 30 days. Maybe purged sooner. Generated by WNS.
    • PushNotificationChannelManager win8
      HttpNotificationChannel.Find WindowsPhone7
    • ToastContentFactory from Nuget
    • If building your own the WNSRecipe and NPNSRecipe help

    APP204:From Web to Windows - Designing Modern Windows 8 Apps using HTML, CSS and JavaScript

    Presenter: Gus Pickering, Sam Langley and Zach Hitchcock

    • Application Experience Review (AER) was used for early apps. Highly recommended to go through if you can.
    • Expression Encoder for screen captures.
    • Ensure you include a privacy policy (required if you have internet capability) and a support email address in the app.
    • Typically use 7+ for the age limit unless there is a reason to set it lower.
    • Many different ways to imply a grid, color, size, proximity, shape,
    • User Experience:
      • Make your hit areas bigger
      • Snapped view is important
      • Include portrait (unless good reasons not to)
      • Use semantic zoom
    • Skeuomorphism - making things look like their real world counterpart.
    • For testing - Use a second portrait monitor to test orientation. (or the simulator)
    • Learning JavaScript as a programming language
      JavaScript: The Good Parts. Douglas Cockford.
    • JavaScript Libraries
      Using existing libraries will probably contain unnecessary compatibility code for other browsers.
    • Useful Tools:
      • Visual Studio 2012 - JavaScript Console, DOM Explorer, Simulator
      • Fiddler.
        - Composer - send Get/Put requests to a URL Manually put in values.
        - AutoResponder - fiddler intercepts and responds with your predefined response
      • Javascript libraries
        - Underscore.js - Give functions similar to Linq queries in JavaScript
      • JavaScript
        - Mozilla Developer Reference
        - Be disciplined with conventions and testing to avoid issues due to lack of typing system. Write defensive code for type checking.

    APP205:Practical Metro - Build Stunning and Innovative Windows 8 Apps Rapidly

    DEV305:Enjoy A Cup Of CoffeeScript


    DEV401:It's .NET, Jim, but not as we know it...

    Presenter: Ivan Towlson

    • Windows Runtime C# classes must be sealed. Can't have generic classes in a public interface. Internal components can.
    • Windows Runtime C# structs can only contain public fields, and nothing else. A C# class can't contain public fields.
    • You can't create your own public exception classes, only use the predefined sealed type.
    • You can't have ref parameters in a public method.
    • These restrictions don't apply to pure .NET libraries. Only those targeting the Windows Runtime.
    • Javascript doesn't support inheritance. Hence all public classes need to be sealed. They can do it internally as they can code special cases (projections?) in WinRT.
    • Portable class library (.NET class library) that can be consumed by and .NET runtime and .NET in WinRT.
    • .winmd files. MetaData files for the runtime. Can be opened by IL DASM.
    • Catalog of all the classes used in an app are stored in the registry.
    • Windows Runtime is built on COM.
    • Language projections generally protect you from COM. Hence can't define own exception types as that is all the COM supports.

    APP206:The Interaction Continuum

    Presenter: Mark Manderson

    • As you move further from the screen it is harder to do content creation. Becomes more about consumption.
    • Covered pros and cons of:
      • Voice Recognition:
        + Control area is large
        + Very little user training required
        + A natural communication mechanism
        - Machine may need training to be effective
        - Natural human speech patterns are hard to parse
        - Noise cancellation required
        - High machine load
        - user frustration
      • Depth Cameras:
        + Skeletal/Hand tracking for posing and gestures
        + Face and Head tracking
        + Recognition of a specific user
        + Interaction at medium distance
        + Natural Gestures
        - Can only show a limited amount of information.
        - Can require exaggerated movement
        - A heavy software layer
        - Occlusion - More than one user
        - User Fatigue
      • Sensor Fusion:
        + Can infer environmental factors
          - Orientation, location, movement, etc...
          - Environmental effects on user
        E.g. Augmented reality systems.
      • Touch:
         + Now cheap and ubiquitous
         + Windows 8 is very touch centric
         + Natural User Interface
        - Fat Fingers
        - The Ghost touch - quirks of the sensor technology
         - "Gorilla Arm" - Sore arms after extended usage.
         - Lack of haptic feedback - no physical feedback.
      • Direct Input Mechanisms:
        + Used where precision is required
         + Great for content creation
         + Allows economy of movement - reduces fatigue..
        - Must be very close to the machine
        - OOS/Repetitive strain injury
         - Considerable training can be required
         - Not natural - an abstraction

    APP301:Everything You Need to Know About Building REAL XAML Apps for Windows 8

    Presenters: Ben Gracewood and Nigel Sampson

    Demo source code.

    • Use device independent pixels to allow scaling. Gives independence from the device resolution.
    • XAML Spy, select visual elements
    • Support for Snap View "Snapped" and portrait
    • /Common/BindableBase.cs - CallerMemberName Attribute to implement INotifyPropertyChanged. Also CallerFilePath and CallerLineNumber.
          public sealed class Logger
          {
              public static void TraceMessage(string message,
                                       [CallerMemberName] string memberName = "",
                                       [CallerFilePath] string sourceFilePath = "",
                                       [CallerLineNumber] int sourceLineNumber = 0)
              {
                  Console.WriteLine("message: " + message);
                  Console.WriteLine("member name: " + memberName);
                  Console.WriteLine("source file path: " + sourceFilePath);
                  Console.WriteLine("source line number: " + sourceLineNumber);
              }
          }
      
    • DefaultViewModel (from File > new project) is just IObservableMap<...> this.DefaultViewModel["Groups"] = //...
      Typically the first thing to throw away from the default templates.
    • ReSharper gives intellisense for StaticResources.
    • SemanticZoomView - Give more information in the zoomed out view than just square tiles if possible.
       - Not an optical Zoom
       - If your grid is grouped then have semantic zoom.
       - Pretty much impossible to extend
       - A lot of scope for creativity
       - Can be more than just navigation
      Currently only one level of zoom. Should continue to show the same information at the same level. 
      
    • Async/Await [41:30]
      override OnUnhandledException
      In async void methods an unhandled exception gets put onto the default stack pool and causes the application to crash out rather than handle the exception.
      Anywhere there is an async void ensure you add exception handling as OnUnhandledException won't catch it.
    • Helper method. HandleErrors to wrap any async void. [46:30]
      private async void HandleErrors(Func<Task> action)
              {
                  try
                  {
                      await action();
                  }
                  catch (Exception ex)
                  {
                      DisplayError(ex);
                  }
              }
      
              private async void DisplayError(Exception ex)
              {
                  var dialog = new MessageDialog(ex.Message, "Unhandled exception in Application!");
      
                  await dialog.ShowAsync();
              }
      
    • If the method returns Task<T> ensure there is an await in the call or any exceptions will be swallowed up.
    • Code52 tool to reset highlight colour - HAMMER.Pants.exe Change cool in theme resources. Take generated file (Generic.xaml) and add to App Resources folder. Include it with the other Resource dictionaries (In App.xaml > ResourceDictionary.MergedDictionaries).

    INO202:Building Roborazzi, a Kinect-Enabled Party Photographer Robot

    DBI305:Practical Uses and Optimisation of New T-SQL Features in Microsoft SQL Server 2012


    DEV311:Turbocharge your Productivity with Visual Studio

    Presenter: Bevan Arps

    • Environment - Light or Dark color theme.
    • Consider using a proportional rather than fixed width font.
    • Ctrl+, Search for objects, methods
    • Solution Explorer now has a search box. Solution Navigator in Visual Studio 2010 productivity power tools is the earlier prototype.
    • Visual Studio Test Explorer has adapters for running nunit and other testing frameworks.
      Option to automatically run tests after a build.
    • Create a custom ruleset for code analsys and then save the .ruleset file at the root of the project. Create a separate build configuration that does a debug build and adds in the Code Analysis.
    • DebuggerDisplay attribute to change display of instance
      [DebuggerDisplay("Count = {count}")]
      class MyHashtable
      {
          public int count = 4;
      }
      

    DEV313:WebAPI: Know It, Learn It, Love It

    Presenter: Grant Archibald @garchibald

    • WebAPI is designed to work across HTTP. New Framework to easily Send/Receive data over HTTP to a range of clients.
    • Data format agnostic but usually JSON or XML
    • Easy to consume from JavaScript!
    • Add packages for help and odata.
    • Add a SecurityException Filter. Only return the top level exception message
    var client = new HttpClient(handler);
    client.DefaultRequestHeaders.Add("Accept", format);
    await client.GetAsync(url);
    await client.PostAsync(url, … JsonConvert …);
    await client.PutAsync(url, … JsonConvert …);
    await client.DeleteAsync(url);
    
    $.ajax({
     url: '/api/Members',
     contentType: 'application/json',
     dataType: 'json',
     type: 'GET',
     success: function(…) { },
     error: function(…) {}
    );
    

    See Also:


    ARC401:Hack-Ed: Design for Attack

    DEV314:What's New for Unit Testing in Visual Studio 2012

    • Continuous Testing - Run Tests After Build
    • Support for different testing frameworks
    • Reduced number of windows to work with

    APP304:Using PhoneGap to Write Once, Look Metro and Run On All Mobiles

    Presenter: Kevin Isom - @kev_nz

    • www.phonegap.com
    • Allows you to make a mobile web application and deploy it to the suitable store for the device.
    • Also allows you to talk to the hardware. Camera, messaging, audio recording.
    • A weakness is animation support. Especially when using PhoneGap on WP7.
    • Still a Windows Phone App under the hood. Could easily create a hybrid application.
    • www subfolder can be common with other phone platforms.
    • Won't have support for touch events in WP7. Need to use click events, which are a bit slower.
    • If your app is your product, write native for each device.

    INO201:Building Robots - Getting Started with the .NET MF and .NET Gadgeteer


    APP305:Working with Windows 8 Sensors, Devices, Proximity and Near Field Communication (NFC)

    Presenter: Lewis Benge

    • Seamless access to devices under Windows 8
    • Play To for streaming to TVs. Industry standard DLNA.
    • CameraCaptureUI
      Control for built-in camera control with pre-defined user workflow.
      Similar to 'pick' photos or videos from the file system
      Specify quality of capture
      Set Timers
    • WIN8 minimum hardware spec
      Ambient Light
      Motion Sensor Fusion
      Windows Location Provider
      GPS (if mobile hardware is present)
    • Location
      Every single Windows 8 can provide location data (if the user allows it)
      Includes enrichment from bing maps.
    • Light-aware apps. Adjust for Dark, Indoors, Outdoors. Contrast adjustment on Visual State.
    • ST Microelectorincs eMotion Development Board
    • Near Field Communication (NFC)
      Under the Windows.Networking namespace.
      Tags are read/write. Not powered, no batteries.
    • Windows.Devices.Enumeration - Device discover and notifications about devices.
    • Windows RT devices don't expose low level bluetooh devices.
    • Companion app - automatically installed when hardware is added.
    • Windows 8 SDK samples - Media Capture

    DEV315:JavaScript - Not Your Mother's Scripting Language

    SIA302:Hack-Ed: Mobile Security

    APP208:Windows Phone: What's New

    APP303:Create Your Own Lego: Building Custom Controls for Windows 8 Apps


    DEV402:Multi-threaded Programming in .NET from the ground up

    Presenter: Orion Edwards

    [Source]
    • Interlocked methods - Atomic in nature. Increment, Decrement, Exchange, CompareExchange, Add [6:00]
    • The C# and JIT compilers only consider the single-threaded case when optimizing. Behaviour depends on the environment/platform. [13:27]
    • Volatile keyword - ensures the compiler doesn't optimise the the usage and create bugs. [14:19]
    • The CPU rearranges the order of reads and writes to memory! [16:00]
      Each CPU keeps track of it's own reordering, but doesn't inform the others. [19:30]
      Solutions:
      • Use a lock - Standard Lock inserts appropriate barriers behind the scene.
      • Memory Barrier - Thread.MemoryBarrier
    • Memory Model x86 and x64 will only reorder "Stores reorders after Loads".
      ARM processors may do significantly more reorderings.
    • Lock-free programming
      Interlocked.CompareExchange
      Your data structure must be immutable - allows multiple threads to read concurrently
    • Lock-Free Performance benefits are hard to get. Almost always better off using locks
    • Threading Model
      What threads can access what data?
      What threads exist and can I create more?
      • No threading model
      • Single Event Loop
      • Single Event Loop + workers
      • Multiple event loops
    • Programming/Debugging tips
      All threading bugs are caused by access to shared data
      Avoid it where possible
      Make it immutable where possible
    • Deadlocks are usually easy to solve with Memory dumps.
    • Don't run arbitrary unknown code while holding locks. E.g. Don't fire a change notification within the lock.
    • Create attributes that can make classes/members as threadsafe of on the UI thread.

    APP306:WP7 Silverlight DataBinding: How exactly do you do that?


    DEV312:Web Development, the Next Step


    DEV307:Single Line Solutions from the .NET Framework

    Presenter: Bevan Arps

    • INotifyPropertyChanged implementation can be simplified in .NET 4.5 using CallerMemberName attribute
    • Nullable<T> now has .GetValueOrDefault(foo) as an alternative to ??
    • Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) .NET 4.0 [8:00]
    • XPath get xpath evaluation result:
      var namedSubsections = document.XPathEvaluate("section/subsection[@name]"); [18:45]
    • Linq [19:40]
      .TakeWhile discard all that match the condition. Stops as soon as the condition is false.
    • Lazy - Allows for single instantiation and has support for thread safety.
    • ThreadLocal - One instance per thread. [21:30]
    • MoreLINQ - Linq extensions from Jon Skeet
      .MaxBy - Find the highest value.
      .Concat() appends onto the end of the sequence
      .ForEach() for enumerable in addition to the built in support for List.
      .Pipe() applies an action to each item as it passes through the sequence.
    • AsCount - create an extension method on int that allows formatting for singular and plural
    • Exception.AsEnumerable extension method creates a sequence from the root exception and the inner exceptions.
    • AsStrings extension method to extract Data property key value pairs form exceptions. Includes checking for nulls. Every Exception in .NET has a Data property.
    • Chained Null checks
      With - takes an input object and a function
      Return - value or default.

    INO401:The Technology Behind Kinect - The Box of Awesomeness

    Wednesday, September 5, 2012

    APP204 From Web to Windows - Designing Modern Windows 8 Apps using HTML 5, CSS & JavaScript

    Presenter: Gus Pickering, Sam Langley and Zach Hitchcock

    Application Experience Review (AER) was used for early apps. Highly recommended to go through if you can.
    
    Expression Encoder for screen captures.
    
    Include a privacy policy and a support email address.
    
    Typically use 7+ for the age limit unless there is a reason to set it lower.
    
    No more browser compatibility issues (with JavaScript Windows Apps). If it works for me, it'll work for everyone.
    
    
    The Windows UI Design Language
     - Learn the language
     - Put users first - content before chrome
     - Know your content
     - Use the grid wisely
     - Good typography is very powerful
    
    
    The Grid
    Fundamental to organise information.
    Many different ways to imply a grid, color, size, proximity, shape,
    
    Interaction
    Animation enhances comprehension
    Stay Simple, but clever
    
    
    Information Architecture
    
    User Experience
    Make your hit areas bigger
    Snapped view is important
    Include portrait (unless good reasons not to)
    Use semantic zoom
    
    Design
    Use colour, contrast and size
    
    Panning
    Windows UI is a horizontal world
    Don't forget about portrait.
    
    
    Skeuomorphism - making things look like their real  world counterpart.
    Offers a shallow learning curse for users but you are also modelling the constraints
    Use spatial dimensions not available in the real world.
    But sometimes a button needs to be lickable.
    
    Media queries make the browser engine do the hard work.
    
    
    CSS3 Layout and Typography
    Grid Layout
     display: -ms-grid;
    Flexbox
     display: -ms-flexbox;
    Floats done the right way.
    
    Multi column layout
    
    Exclusions
    -ms-wrap-flow:both
    
    JavaScript Libraries
    Underscore
    Will probably contain unnecessary compatibility code.
    
    Test
    Use a second portrait monitor test orientation.
    
    
    
    Learning JavaScript as a programming language
    JavaScript: The Good Parts. Douglas Cockford.
    
    Avoid: Sams Tech Yourself JavaScript in 24 Hours
    
    Useful Tools:
    
    Visual Studio 2012
     - JavaScript Console, DOM Exporer, Simulator
    Fiddler,
     - Composer - send Get/Put requests to a URL Manually put in values, 
    - AutoResponder - fiddler intercepts and responds with your predefined response
    Javascript libraries
     - Underscore.js - Give functions similar to linq queies in JavaScript
    JavaScript
     - Mozilla Developer Reference
    
    Be disciplined with conventions and testing to avoid issues due to lack of typing system. Write defensive code for type checking.
    
    

    Thursday, August 30, 2012

    Load testing with loadUI and a Console Application using WebBrowser

    To load test an ASP.NET web application I created a Console Application that simulated the process one user would go through to complete adding a new order, from automatic login, to product selection, to logout.

    The Console Application

    1. Create a thread to host an instance of System.Windows.Forms.WebBrowser in.
      See WebBrowser Control in a new thread
    2. Create the URL that the user navigation will start from. The included single sign on details that would establish the Session.
    3. Register for the DocumentCompleted event from the WebBrowser so I can detect when the page has been completely loaded.
    4. Call WebBrowser.Navigate() with the URL.
    5. Start the STA Thread running.
    6. When the DocumentCompleted event fires check if the event args URL matches the browsers URL.
    7. If the URLs match the navigation has been completed and the browser can be transitioned to the next step.
    8. Use WebBrowser.Navigate("javascript: document.getElementById('ctl00_MainContentPlaceHolder_btnContinue').click();"); to simulate the user pressing the Continue button.
    9. Keep checking the DocumentCompleted event until the WebBrowser reaches a page that indicates the process is complete. When it is, exit the thread to return to the main program. System.Windows.Forms.Application.ExitThread();
    10. The Console Application would close with and Exit Code of 0 if the process was successful. Otherwise the Exit code would correspond to a enum flag indicating what issue was encountered.

    Why use a WebBrowser instance rather than HttpWebRequest/HttpWebResponse and a CookieContainer?

    I started down this path but there were a couple of issues.

    Firstly, this would only send the requests I explicitly coded for where as the WebBrowser will load the page like a user would. For load testing this made the WebBrowser more realistic as it would also send requests for CSS, JavaScripts, Images and iframes before considering the load complete

    Using loadUI to start and monitor the Console Application

    • Create a Fixed Rate Generator
    • Connect it to a Process Runner

    Sorting WSDL type elements using XSLT before using Salesforce wsdl2apex

    After using the Salesforce wsdl2apex to generate apex I'll often need to make some tweaks by hand to allow for automated testing.

    When regenerating for WSDL updates I've found the order of the elements can change dramatically. With large WSDLs this can make migrating the changes by hand a time consuming exercise.

    For example, below is the SourceGear DiffMerge overview from two versions of a 5000 line WSDL. (Turned on it's side)

    WSDL diff

    It isn't clear to me why the order of the XML elements is changing so much between versions, but it does make tracking the actual differences more difficult.

    One possible solution I've found is to run the WSDL through an XSLT to sort the various elements by name.

    I've appropriated the following from Glen Mazza - Using XSLT to organize SOAP contracts (WSDLs and XSDs)

    One easy way to apply it is to open the WSDL in Visual Studio as XML and then use XML > Start XSLT Debugging to apply it.

    After processing the line counts went from 3475 and 5005 to 3472 and 5002 respectively. Now I can clearly see where new elements have been added in the diff:

    WSDL diff after sorting
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE stylesheet [
    <!ENTITY space "<xsl:text> </xsl:text>">
    <!ENTITY ivSp "<xsl:text>    </xsl:text>">
    <!ENTITY tab "<xsl:text>	</xsl:text>">
    <!ENTITY cr "<xsl:text>
    </xsl:text>">
    ]>
    
    <xsl:stylesheet version="1.0"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns:xs="http://www.w3.org/2001/XMLSchema"
       xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
       xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
       xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
    
       <xsl:template match="wsdl:definitions">
           &cr;
           <!-- By itself, xsl:copy outputs only the element referred to.
                It needs additional coding as below to copy the
                element's attributes and descendant elements.
           -->
           <xsl:copy>
              <!-- output all attributes of the top-level element -->
              <xsl:for-each select="@*">
                  <xsl:copy/>
              </xsl:for-each>&cr;
    
              <xsl:for-each select="./wsdl:types">
                  &ivSp;<wsdl:types>&cr;
                      <xsl:apply-templates select="./xs:schema"/>
                  &ivSp;</wsdl:types>&cr;
              </xsl:for-each>
    
              <xsl:for-each select="./wsdl:message">
                  <xsl:sort select="@name"/>
                  <xsl:apply-templates select="."/>
              </xsl:for-each>
    
              <xsl:for-each select="./wsdl:portType">
                  <xsl:apply-templates select="."/>
              </xsl:for-each>
    
              <xsl:for-each select="./wsdl:binding">
                  <xsl:sort select="@name"/>
                  <xsl:apply-templates select="."/>
              </xsl:for-each>
    
              <xsl:for-each select="./wsp:Policy">
                  <!--if wish to sort: xsl:sort select="@wsu:Id"/-->
                  &ivSp;<xsl:copy-of select="."/>&cr;
              </xsl:for-each>
    
              <xsl:for-each select="./wsdl:service">
                  &ivSp;<xsl:copy-of select="."/>&cr;
              </xsl:for-each>
    
           </xsl:copy>
    
       </xsl:template>
    
       <!--
          Each immediate child of the top-level element is indented four spaces
          from the top-level item.  May need to convert original WSDL from tabs
          to spaces first.
       -->
       <xsl:template match="wsdl:message">
           &ivSp;<xsl:copy-of select="."/>&cr;
       </xsl:template>
    
       <xsl:template match="wsdl:portType | wsdl:binding">
        &ivSp;<xsl:copy>
              <!-- output all (@*) attributes of the top-level element -->
              <xsl:for-each select="@*">
                  <xsl:copy/>
              </xsl:for-each>&cr;
         
              <xsl:for-each select="./*[not(self::wsdl:operation)]">
                  &ivSp;&ivSp;<xsl:copy-of select="."/>&cr;
              </xsl:for-each>
    
              <xsl:for-each select="./wsdl:operation">
                  <xsl:sort select="@name"/>
                  <xsl:apply-templates select="."/>
              </xsl:for-each>&ivSp;
    
            </xsl:copy>&cr;
       </xsl:template>
    
       <xsl:template match="wsdl:operation">
           &ivSp;&ivSp;<xsl:copy-of select="."/>&cr;
       </xsl:template>
    
       <xsl:template match="xs:schema">
    
           &ivSp;&ivSp;<xsl:copy> 
              <!-- output all (@*) attributes of the top-level xs:schema element -->
              <xsl:for-each select="@*"> 
                  <xsl:copy/>
              </xsl:for-each>&cr;
              
              <xsl:for-each select="./xs:import">
                  <xsl:apply-templates select="."/>
              </xsl:for-each>
          
              <xsl:for-each select="./xs:simpleType">
                  <!-- sort the simpleTypes by their name attribute first -->
                  <xsl:sort select="@name"/> 
                  <xsl:apply-templates select="."/>
              </xsl:for-each>
          
              <xsl:for-each select="./xs:complexType">
                  <xsl:sort select="@name"/>
                  <xsl:apply-templates select="."/>
              </xsl:for-each>
    
              <xsl:for-each select="./xs:element">
                  <xsl:sort select="@name"/>
                  <xsl:apply-templates select="."/>
              </xsl:for-each>
           &ivSp;&ivSp;</xsl:copy>&cr;
    
       </xsl:template>
    
       <xsl:template match="xs:import | xs:simpleType | xs:complexType | xs:element">
           <!-- Unlike xsl:copy above, xsl:copy-of automatically copies the 
                element's attributes and its descendant elements. -->
           &ivSp;&ivSp;&ivSp;<xsl:copy-of select="."/>&cr;
       </xsl:template>
    
    </xsl:stylesheet>
    

    Saturday, August 25, 2012

    Issues/differences encountered converting WP7 apps to Windows 8

    Tone the Visual Studio 2012 MENUS DOWN

    Changing the All-Caps menu in Visual Studio 2012 to something more readable. Install the VS Commands extension

    Tools > VSCommands > Options > IDE Enhancements > Main Menu > Change Main Menu letter case

    int? Properties in custom user controls

    Binding to a nullable int property in a custom user control produces the following error:

    Failed to create a 'Windows.Foundation.IReference`1<Int32>' from the text '40'. 

    Internally most of the .NET primitive types are converted to equivalent Windows Runtime types. IReference<T> is the Windows Runtime equivalent of Nullable<T> in .NET.

    "Setting nullable properties [in] custom controls is not a supported scenario".

    XAML Error : Value Type Nullable is not allowed on property in XAML Windows 8 Dev Tip: Nullable Dependency Properties and Binding

    Tap Event

    The Tap event with GestureEventArgs becomes a Tapped event with TappedRoutedEventArgs


    MessageBox.Show

    MessageBox.Show is replaced by Windows.UI.Popups.MessageDialog

    MessageDialog.Show("Some Message");
    async private void ShowDialog() {
        await new Windows.UI.Popups.MessageDialog("Some Message").ShowAsync();
    }
    

    There is no WebBrowserTask

    WebBrowserTask task = new WebBrowserTask();
                task.Uri = new Uri("http://www.fishofprey.com/");
                task.Show();
    
    async public void Show()
            {
                await Launcher.LaunchUriAsync(new Uri("http://www.fishofprey.com/"));
            }
    

    General Namespace issues

    "System.Windows" with "Windows.UI.Xaml"

    Differences in StaticResource Styles

    WP7

    Style="{StaticResource PhoneTextTitle3Style}
    

    Windows 8

    Style="{StaticResource SubtitleTextStyle}"
    

    Text Styles

    WP7 NamePossible Windows 8 Style
    PhoneTextNormalStyleBasicTextStyle
    PhoneTextTitle1StyleSubtitleTextStyle

    Brush Resources

    WP7 StylePossible Windows 8 StyleDescription
    PhoneChromeBrushAppBarBackgroundThemeBrushUsed to match the application bar color

    Theme Brushes


    No direct equivalent for the Pivot control

    "The Windows Runtime does not include the Pivot and Panorama controls available in Silverlight for Windows Phone. These controls are designed for the phone form factor, and help users navigate experiences that are larger than the phone screen. Your Metro style apps will usually have more screen space, and should take advantage of the greater flexibility of the Grid control. You can also use the FlipView control to provide a simple paging experience."
    A WinRT behavior to turn a FlipView into a kind of Windows 8 Panorama

    No direct equivalent for the PhoneNumberChooserTask

    Use the Contact Picker contract. Sample

            private async void ActionButtonChoose_Click(object sender, RoutedEventArgs e)
            {
                var picker = new Windows.ApplicationModel.Contacts.ContactPicker();
                picker.CommitButtonText = "Select";
                picker.SelectionMode = Windows.ApplicationModel.Contacts.ContactSelectionMode.Fields;
                picker.DesiredFields.Add(Windows.ApplicationModel.Contacts.KnownContactField.PhoneNumber);
                var contactInformation = await picker.PickSingleContactAsync();
    
                if (contactInformation != null && contactInformation.PhoneNumbers.Count > 0)
                {
                      txtDail.Text = contactInformation.PhoneNumbers[0].Value;
                }
            }
    

    No direct equivalent for the SmsComposeTask or EmailComposeTask

    Windows Phone 7

    SmsComposeTask composeSMS = new SmsComposeTask();
    composeSMS.Body = "Greetings";
    composeSMS.Show();
    

    For WinRT there is SendSmsMessageOperation, but the documentation currently says:

    Note This functionality is only available to mobile operator apps and Metro style apps given privileged access by mobile network operators, mobile broadband adapter IHV, or OEM.

    Another option is to create a mailto URI. I haven't tested this yet, but it looks good in theory.

    var mailto = new Uri("mailto:?to=recipient@example.com&subject=WinRT+email&body=Windows+8+Metro+app.");
    await Windows.System.Launcher.LaunchUriAsync(mailto);
    

    Share the content via the DataTransfer API. How to share text (Metro style apps using C#/VB/C++ and XAML)


    No direct equivalent for the SQL CE database built into Mango using Isolated Storage


    IsolatedStorageSettings isn't available.

    Switch to Windows.Storage.ApplicationData.Current.RoamingSettings or another class under Windows.Storage.ApplicationData.


    PhotoChooserTask isn't in WinRT

    Use CameraCaptureUI

    private async Task CapturePicture()
    {
        var dialog = new CameraCaptureUI();
        dialog.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Png;
    
        var file = await dialog.CaptureFileAsync(CameraCaptureUIMode.Photo);
        if (file != null)
        {
             IRandomAccessStream imageStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
    
        }
        return string.Empty;
    }  
    

    How to Capture Images w/ the WebCam in WinRT (C#) applications.


    Binding doesn't have a StringFormat option

    So a binding like Text="{Binding WordsPerMinute,StringFormat='WPM: {0}'}" results in the errors:

    The member "StringFormat" is not recognized or is not accessible.
    The property 'StringFormat' was not found in type 'Binding'.
    

    Options:


    WrapPanel doesn't (yet) exist in WinRT


    See also:

    Tuesday, August 7, 2012

    WP7 magnetometer data from 360 degree rotation

    This post is a continuation with my unhealthy obsession with why the compass API on Windows Phone 7 doesn't actually point north.

    I captured the following data rotating my Nokia Lumia 800 a full 360 degrees. Admittedly the rotation by hand so there is a fair bit of noise in the readings.

    What it does show is:

    1. the Magnetic Heading drastically changing when it reaches 256°
    2. the declination changing from -129° to +127°

    Magnetic versus True Heading

    Windows Phone 7 Magnetic versus True Bearing

    Scatter plot of magnetometer readings

    Magnetometer Axis Readings by Bearing rotation - radar

    Magnetometer Axis Readings by Bearing rotation - line

    See also: