Connecting UWP Emulator to IISExpress localhost

I’m sure this has been covered a lot, but I’m writing it down so I don’t forget how I did it. If it helps anyone else then great.

1. Locate IIS Express in the system tray

image

2. Select Show All Application in IIS Express, and select your site in the list

image

3. Click on the link in the Config section

Find your site, duplicate the localhost binding element and replace localhost with the IP Address of your machine;

                    
                    

4. With IIS Express tool stop all sites and then re-run your site. NOTE YOU MUST BE RUNNING as Administrator, only admin can allow IIS Express to bind to a non-localhost address

Your emulators should now be able to access the site using your machine’s IP Address.

I’ve found a much nicer explanation Accessing an IIS Express site from a remote computer

Text sizing, symbols and icons

Consider the following XAML;

<TextBlock Text="W" />

; – displays the letter ‘W’ using the text semantics

<SymbolIcon Symbol="Accept" />

– displays the accept tick symbol

<FontIcon FontFamily="Candara" Glyph="& #x3A3;"/> 

– displays the sigma sign as an font icon

<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="& #xE001;"/>

– displays the accept tick again, but as a font icon from the MDL2 assets font family

<TextBlock FontFamily="Segoe MDL2 Assets" Text="& #xE001;" />

– displays the accept tick again but as a text element.

The above all basically do the same. They differ by the semantics, e.g. a screen reader can make different choices based on a text block vs. font icon. However, a not so obvious difference is how they react to the user changing the text size. The following image shows the above rendered with text set to largest and then back to normal text.

image

As you might be able to see, the TextBlock happily resizes the characters, be it a ‘W’ or the tick. The other mechanisms keep the original size. This is important if you want to create buttons in your app. Should your buttons resize with the text or not? Your choice of how you render the symbol/icon will decide the behaviour. IMO it becomes a question of resize vs. element semantics. ‘You make’s your choice’.

How to display icons in Appbar’s secondary menu

By default the secondary menu from an AppBar does not display a icon. However, it’s pretty trivial to change.

<Page.BottomAppBar>
   <CommandBar>
      <AppBarButton Label="A" Icon="Accept" >
         <CommandBar.SecondaryCommands>
           <AppBarButton Label="B" Icon="Accept" Style="{StaticResource AppBarButtonStyle1}" />
         </CommandBar.SecondaryCommands>
   </CommandBar>
</Page.BottomAppBar>

Then in the AppBarButtonStyle1 change the overflow, here is very quick hack to prove the point;

 <VisualState x:Name="Overflow"
  <Storyboard>
     <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ContentRoot">
        <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
     </ObjectAnimationUsingKeyFrames>
     <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="OverflowTextLabel">
        <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
     </ObjectAnimationUsingKeyFrames>
  </Storyboard>
 </VisualState>

and that gives you

secondary

Obviously that is ugly but it is the base of how to provide the icons

How to debug Continuum?

Developing for Continuum poses an initially thorny question, “my phone is plugged into the dock, how can I also plug it into my PC to debug?”. My recommendation is to get yourself a Miracast device and use Continuum’s wireless connection feature. That way your phone can be plugged into your PC for debugging while casting a Continuum desktop to your monitor. If you really need a keyboard and mouse then they’ll have to be wireless too, but the phone’s virtual trackpad and keyboard are enough to get by.

Element to support changing focus in MVVM

The other day I moaned that setting focus to a control in an MVVM environment felt like a painful disconnect. There are probably a dozen ways to resolve this issue, but I thought I’d try to use a method that at least isn’t a Behaviour.

Consider the following snippet of XAML

   <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <local:FocusManagerElement ControlName="{Binding SuggestedFocusName}" />
        <StackPanel>
            <TextBox x:Name="Barny" />
            <TextBox x:Name="Fred" />
            <TextBox x:Name="Bert" />
            <Button Content="Test" Tapped="Button_Tapped" />
        </StackPanel>
    </Grid>

The idea is that the FocusManagerElement is bound to the current view model and will set focus to whatever control is named by the View Model via the SuggestedFocusName property. When the logic in the View Model changes and we want to change the focus the we can simply update that property.

    public class TestViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string suggestedFocusName;
        public string SuggestedFocusName
        {
            get { return this.suggestedFocusName; }

            set
            {
                if (this.suggestedFocusName != value)
                {
                    this.suggestedFocusName = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged.Invoke(this, new PropertyChangedEventArgs("SuggestedFocusName"));
                    }
                }
            }
        }

        public void DoWork()
        {
            // do some logic that means we need to change the focus
            this.SuggestedFocusName = "Fred";
        }
    }

From a developers point of view I think that’s pretty easy and flexible to use. All that remains is to show the implementation of the Focus Manager Element itself;

namespace AppFocusManager
{
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;

    /// <summary>
    /// Element to support setting the focus via a bindable object
    /// </summary>
    public class FocusManagerElement : FrameworkElement
    {
        // Using a DependencyProperty as the backing store for ControlName. 
        public static readonly DependencyProperty ControlNameProperty =
            DependencyProperty.Register("ControlName", typeof(string), typeof(FocusManagerElement), new PropertyMetadata(null, new PropertyChangedCallback(ControlNamePropertyChanged)));

        /// <summary>
        /// Name of control to set focus to
        /// </summary>
        public string ControlName
        {
            get { return (string)GetValue(ControlNameProperty); }
            set { SetValue(ControlNameProperty, value); }
        }

        /// <summary>
        /// Control Name has changed
        /// </summary>
        /// <param name="dependencyObject">the instance of FocusManagerElement</param>
        /// <param name="eventArgs">new name of control to set focus to</param>
        private static void ControlNamePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
        {
            var focusManagerElement = dependencyObject as FocusManagerElement;
            var controlName = eventArgs.NewValue as string;
            if (!string.IsNullOrEmpty(controlName))
            {
                var elementToFocusOn = focusManagerElement.FindName(controlName) as Control;
                if (elementToFocusOn != null)
                {
                    elementToFocusOn.Focus(FocusState.Programmatic);
                }
            }
        }
    }
}

XAML TextBlock Performance gotcha

I’ve been using this.DebugSettings.IsTextPerformanceVisualizationEnabled = true to check on the text performance of my app and noticed this little gotcha. Consider the following code;

    <StackPanel>
        <TextBlock Text="Using text property" />
        <TextBlock>Using text content</TextBlock>
    </StackPanel> 

When you run the app you’ll see the ‘Using text property’ is a pleasing shade of bright green but ‘Using text content’ is not using the optimised text rendering. Cheeky little gotcha. More info (including this) TextBlock