Tag Archives: Windows 10

MVVM Cross Upgrade to 4.2.2

Coming back to MVVMCross and trying to create a new project, I found that some of the documentation available for the new version (4.2.2 at the time of writing this) is no longer correct; for example, the ToDo file in the sample projects still looks like this:

The steps to get this Store UI working are:

1. Add a reference to your Core PCL project
2. Change App.Xaml.cs so that it creates a ‘new Setup(RootFrame)’ during its OnLaunched:

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
var rootFrame = Window.Current.Content as Frame;

// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();

if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}

// Place the frame in the current Window
Window.Current.Content = rootFrame;
}

if (rootFrame.Content == null)
{
// When the navigation stack isn’t restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter

var setup = new Setup(rootFrame);
setup.Initialize();

var start = MvvmCross.Core.Mvx.Resolve();
start.Start();
}
// Ensure the current window is active
Window.Current.Activate();
}

3. For Windows 8 – Add a views folder and a view – xaml.cs and .xaml based on BasicPage – this
will add 5 files to the Common folder.
– Change the Common/LayoutAwarePage.cs inheritance to MvvmCross.WindowsStore.Views.MvxStorePage
– Change the Common/LayoutAwarePage.cs – remove the OnNavigatedTo and OnNavigatedFrom handlers
– Add some content for your Xaml – e.g.

5. For Windows 8.1 – Add a views folder and a view based on the BasicPage template
– In the .xaml.cs – remove public NavigationHelper NavigationHelper and all referencing code
– In the .xaml.cs – remove the OnNavigatedTo and OnNavigatedFrom handlers
– Add some content for your Xaml – e.g.

This document was very useful. I was looking specifically at the Babel project in the above sample; this won’t compile under MvvmCross 4.2.2. I’ve listed here everything I needed to do to make it.

Mvx has now been replaced with MvxSimpleIoCContainer.Instance

In App.xaml.cs:

var start = MvxSimpleIoCContainer.Instance.Resolve<IMvxAppStart>();

Is now:

var start = MvxSimpleIoCContainer.Instance.Resolve<IMvxAppStart>();
start.Start();

In App.cs:

        private void InitializeText()
        {
            var builder = new TextProviderBuilder();
            Mvx.RegisterSingleton<IMvxTextProviderBuilder>(builder);
            Mvx.RegisterSingleton<IMvxTextProvider>(builder.TextProvider);
        }

Is now is a separate plug-in by the looks of things:

mvvmcrossupgrade

The new code is:

        private void InitializeText()
        {            
            var builder = new TextProviderBuilder();
            MvxSimpleIoCContainer.Instance.RegisterSingleton<IMvxTextProviderBuilder>(builder);
            MvxSimpleIoCContainer.Instance.RegisterSingleton<IMvxTextProvider>(builder.TextProvider);
        }

XAML Translations based on the display size in UWP

Having recently released my latest app into the store, I noticed that some of the buttons didn’t fit well on the phone version. I’d already come across translations for the HTML/WinJS version of Windows 8 apps, but not the XAML version, and not Windows 10 UWP.

You can do this in Expression Blend

First, double click the view file:

transuwp1

In the States window, you’ll then have the ability to create a new VisualStateGroup:

transuwp2

Create the required states; here’s mine:

transuwp3

If you click the lightning bolt to the side of the group, you should get the following:

transuwp4

If you create an adaptive trigger as above, you’ll be able to set the minimum width or height for the change. I’ve set the minimum width for desktop form factor to 500.

Back to code

What that produces for you (remember that you can alt-tab between Blend and VS and it should deal with the changes relatively gracefully) is a piece of code along the lines of this, within the XAML view:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <VisualStateManager.VisualStateGroups>

            <VisualStateGroup x:Name="VisualStateGroup">

                <VisualState x:Name="Normal">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="500"/>
                    </VisualState.StateTriggers>
                </VisualState>

                <VisualState x:Name="Mobile">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="320"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="tgPlay.(Grid.Column)" Value="0"/>
                        <Setter Target="tgPlay.(Grid.Row)" Value="1"/>
                        <Setter Target="btnCommandCreateVideo.(Grid.Row)" Value="1"/>
                        <Setter Target="btnCommandCreateVideo.(Grid.Column)" Value="1"/>
                        <Setter Target="btnCommandClear.(Grid.Row)" Value="1"/>
                        <Setter Target="btnCommandClear.(Grid.Column)" Value="2"/>
                        <Setter Target="numericUpDown.(Grid.Column)" Value="0"/>
                        <Setter Target="numericUpDown.(Grid.Row)" Value="1"/>
                        <Setter Target="numericUpDown.(Grid.ColumnSpan)" Value="3"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

There’s a number of points here – the first is that you need to name your controls; that’s how they are referenced. If you use Blend and you don’t do this then blend will give them a name; for example, I didn’t give “numericUpDown” a name. If I had another control of the same type then it would just number them.

The second point is the adaptive trigger. 500 and 320 seem to be the generally accepted divisions between desktop and narrow form factor. This approach worked for my specific requirement, although what Blend produces does require some re-work, otherwise it just ends up as a mess.

InkCanvas

Pointlessly Long Introduction (feel free to skip)

Some time ago, in a previous job, I was asked to add spell checking to a WPF textbox. I did some research as to how to do that, and came to the conclusion that the only way was using MS Word automation. I must have spent a good three or four hours writing code that interrogated Word and performed spell checking. It wasn’t until I got to auto correct that one of my searches threw up a property on the text box: “SpellCheck.IsEnabled”.

(At the time of writing) I recently attended a developer conference, and at it, I was shown a control called InkCanvas! Having recently spent a considerable amount of time trying to use a Canvas for drawing, I felt like I’d just found the SpellCheck.IsEnabled property again.

Using the InkCanvas Control

In comparison to the Canvas, the InkCanvas basically works out of the box. If you use the InkToolbar with it, you’ll get some errors, but they aren’t actually errors; for example:

1>C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(2048,5): warning MSB3781: The SDK “InkToolbarControl, Version=0.3.2” depends on the following SDK(s) “Microsoft.VCLibs, version=14.0”, which have not been added to the project or were not found. Please ensure that you add these dependencies to your project or you may experience runtime issues. You can add dependencies to your project through the Reference Manager.

Here’s the XAML that I used to get it working. Don’t be phased by the fact that x:Bind doesn’t seem to resolve.

            <InkCanvas x:Name="drawInkCanvas">                    
            </InkCanvas>
            <inkTools:InkToolbar TargetInkCanvas="{x:Bind drawInkCanvas}" 
                                PenColor="#FFE61021" 
                                VerticalAlignment="Top" HorizontalAlignment="Right"/>

Enabling Input

I found only one thing that caused confusion, and it took a while to solve. Basically, the above XAML doesn’t allow you to actually draw anything; you need this:

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            drawInkCanvas.InkPresenter.InputDeviceTypes =
                Windows.UI.Core.CoreInputDeviceTypes.Mouse |
                Windows.UI.Core.CoreInputDeviceTypes.Pen |
                Windows.UI.Core.CoreInputDeviceTypes.Touch;

        }

Saving the Image

To save what you’ve drawn, you can use something similar to this code:

            if (canvas != null && canvas.InkPresenter.StrokeContainer.GetStrokes().Count > 0)
            {
                if (file != null)
                {
                    using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                    {
                        await canvas.InkPresenter.StrokeContainer.SaveAsync(stream);
                    }
                }
                Clear(canvas);
            }

WPF Drawing Application

The following is a XAML page that allows the user to draw on it. This was written and tested under a Windows 10 desktop application, but should work for WPF. Here’s the XAML:

        <Grid>
            <Border>
                <Canvas PointerPressed="Canvas_PointerPressed" PointerMoved="Canvas_PointerMoved"
                        PointerReleased="Canvas_PointerReleased"
                        Background="Orange" Name="Canvas" />
            </Border>
        </Grid>

The background is a different colour to identify the canvas.

There’s the code to allow drawing:

        
        Path _currentPath;

        private void Canvas_PointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
        {            
            _currentPath = new Path
            {
                Data = new PathGeometry
                {
                    Figures = { new PathFigure
                    {
                        StartPoint = e.GetCurrentPoint((UIElement)sender).Position,
                        Segments = { new PolyLineSegment() }
                    }}
                },
                Stroke = new SolidColorBrush(Colors.Black),
                StrokeThickness = 5
            };

            Canvas.Children.Add(_currentPath);
        }

        private void Canvas_PointerMoved(object sender, PointerRoutedEventArgs e)
        {
            if (_currentPath == null) return;

            var pls = (PolyLineSegment)((PathGeometry)_currentPath.Data).Figures.Last().Segments.Last();
            pls.Points.Add(e.GetCurrentPoint((UIElement)sender).Position);
            
        }

        private void Canvas_PointerReleased(object sender, PointerRoutedEventArgs e)
        {
            _currentPath = null;
        }

As you can see, it doesn’t do anything for my drawing ability:

drawing

It’s all the code behind and, while I typically shy away from this, it seems to fit well for an application such as this (as the drawing relates more to the view than to anything else).

Load and Display a list of Images in Windows 10

The following is a quick tutorial on how to load a series of images from the machine and display them on screen. This is something that I’m working on for my next Store Application.

The XAML

Let’s start with the screen layout – the GridView control makes this quite an easy task in Windows 10:

            <GridView ItemsSource="{Binding Images}">
                <GridView.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding}" Stretch="Uniform" 
                               Width="100" Height="100"/>
                    </DataTemplate>
                </GridView.ItemTemplate>
            </GridView>

Binding

In this case, I have bound the view to a ViewModel; the relevant part of which looks like this:

        private ObservableCollection<BitmapImage> _images;
        public ObservableCollection<BitmapImage> Images
        {
            get
            {
                if (_images == null)
                {
                    _images = new ObservableCollection<BitmapImage>();
                }
                return _images;
            }
            set
            {
                _images = value;
                NotifyPropertyChanged();
            }
        }

Basically, just an observable collection of BitmapImage.

Load the Image

Here’s where we populate the list:

        private async void Load()
        {
            FileOpenPicker openPicker = new FileOpenPicker();
            openPicker.ViewMode = PickerViewMode.Thumbnail;
            openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
            openPicker.FileTypeFilter.Add(".jpg");
            openPicker.FileTypeFilter.Add(".jpeg");
            openPicker.FileTypeFilter.Add(".png");
            openPicker.FileTypeFilter.Add(".gif");

            StorageFile file = await openPicker.PickSingleFileAsync();
            if (file != null)
            {
                var fileStream = await file.OpenAsync(FileAccessMode.Read);

                BitmapImage bi = new BitmapImage();

                bi.SetSource(fileStream);
                Images.Add(bi);

            }            
        }

Conclusion

I spent a short period of time wondering what had happened to the UniformGrid for Windows 10, but as you can see, the GridView just makes this job much easier.

OCR in Windows 10

Believe it or not, Windows 10 comes with OCR capabilities out of the box. It’s actually very easy to use as well; admittedly, it’s not the most sensitive in the world – but it does basically work. Here’s how you would scan in a bitmap image and recognise characters:

        public async string RecogniseOCR()
        {                        
            var ocrEngine = Windows.Media.Ocr.OcrEngine.TryCreateFromLanguage(new Windows.Globalization.Language("en"));
            
            var file = await Package.Current.InstalledLocation.GetFileAsync(@"Assets\test.bmp");            
            using (var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
            {
                // Create image decoder.
                var decoder = await BitmapDecoder.CreateAsync(stream);

                // Load bitmap.
                var bitmap = await decoder.GetSoftwareBitmapAsync();

                // Extract text from image.
                OcrResult result = await ocrEngine.RecognizeAsync(bitmap);

                // Return recognized text.
                return result.Text;
            }
        }

I scanned this image:

OCRScan

And it found this:

OCRScan2

Like I said – not the most sensitive recognition in the world, but still, it’s there in Windows 10! What’s remarkable is that I only found it by accident – another example of Microsoft marketing missing a huge opportunity.

Targeting Windows 10 Desktop Device Family

Having upgraded to Windows 10 recently, I came across an idea for a new app. Part of what this app is supposed to do it allow scanning of an image. Whilst I found a number of helpful articles of the code to scan an image, they seemed to make an assumption that the reader knew how to target the Desktop Device Family.

Reference the Extension for Desktop Applications

Windows 10 has a number of specific extensions for specific targeted devices. The first step is to reference in the correct one:

Extensions

Change the target in you Package.appxmanifest file

If you have a look in the UI menu for this, you won’t find any way to change the targeted device family (at least I didn’t). So, you need to change the XML:

  <Dependencies>
<!--    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
--> 
	  <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0"/>
  </Dependencies>

Windows 10 – The Return of the Overrated Start Menu

Yesterday, for the first time, I saw Windows 10. I set it up in a VM inside Win 8. The following post in a combination of conjecture, opinions, and under researched hearsay.

First, let’s think about what I just said: I’m running a later version of Windows inside an earlier one. And it works.

9

Don’t mention 9! I mentioned it once, but I think I got away with it.

Start menu

The start menu never went anywhere for Win 8. You just press the Windows key and you’re in it (although it was more of a screen than a menu). Anyway, MS finally bowed to pressure, and it’s back:

start1

Looks good eh? Actually, after restarting it seemed to gather its thoughts:

start2

Anyway, as I understand the intention, if I were running this on a tablet, I’d be able to see the Win 8 start screen when I pressed the Windows Key. I can’t test that on a VM and, if I could, I’d be surprised if it worked properly for the TP.

Multiple Desktops

This is a neat feature: the ability to maintain more than one desktop. The way this appears to work is that you can open apps into any desktop, and then just switch between desktop to access them, or access them from the taskbar, and Windows will select the desktop they are on.

desktop

You appear to be able to maintain as many desktops as you like.

Search

There is a large magnifying glass on the taskbar, which brings up a huge, unwieldy, blank box with a small text search. Maybe this will be back on the charms bar for tablets, but the idea is that it will find stuff on your machine. It failed:

search

I don’t understand why this was separated from the start menu. Searching for, and running programs are basically the same thing. If I want to run word, I want to type “Word”; if I want to open a word document on my desktop, I want to type: “My word doc” and have it find it. Results seemed to be sporadic, sometimes it found what I expected, but generally it didn’t.

What happened to the charms bar?

It now seems to be a sub menu of each store window:

charmsbar

As I said earlier, I expect it will behave differently for the tablet and phone.

Universal Apps

These have been around for a while. They basically allow sharing of code between Windows store and Windows phone apps. As I understand it, these will now be effectively mandatory – you will have to produce a phone & store version, in the same way as you had to provide a snapped and filled version of your app.

Conclusion

The split desktop is nice, and the idea of having “One Windows” is a nice one. In fact, it’s effectively what I understood to be the driving force behind 8. It looks like it’s going to be a good OS, but I can’t see any killer features.

What I mean by that is this: imagine that you want to upgrade to Windows 10, and you put the idea to your boss. The first question they should ask is: “Why?”.

For Windows 8, the answer was simple: Hyper-V. An astoundingly useful and undersold feature.

Windows 10 doesn’t have that, and it needs it, because a lot of people are sticking on 7 and need a reason to upgrade – having the start menu back is not that reason.