[Survey] Windows Phone and Windows Store Dev Experience – 2014

As we continue to improve the Windows developer experience, the Windows Apps teams need your help.

5-10 minutes of your time can greatly help the team better understand how the WPDev community is using the Windows and Windows Phone platforms and tools. Your answers and insights will help determine what developer resources are as we continuously improve the SDK(s) and how we support the community’s needs. Additionally, the team can (and will) share top-level results from your survey responses back out to the community.

This survey is designed to take 8 minutes – depending on how much deep feedback you care to share, your mileage may vary.

Windows Developer Survey Privacy Statement (last updated: November-14-2011)
Microsoft is committed to protecting your privacy. Your responses to this survey will not be linked to any contact information previously collected by Microsoft. Your answers will be reported in aggregate with those of other respondents. This survey collects information about your response such as the Internet Protocol (IP) address through which you access the Internet and the date and time you access the survey. This information is used to help improve the survey, analyze trends, and administer the survey. Please note that this privacy statement applies only to this survey. It does not apply to other online or offline Microsoft sites, surveys, products or services.

Please contact cliff.simpkins@microsoft.com if you have any questions concerning collection and use of your personal information.

Microsoft’s Windows App Studio Beta: Submit Menu App in the Store

Scope

This article aims to show how to submit, in the Store, the Menu App created by Windows AppStudio. See more in the following articles

Introduction

Publish an application in the Windows Store is the last step we need to do for have the application available in the store, but publish the application is not only to take a package and add it to the store, there are some steps we need to do.

In general, the main steps we must do are

  • Test the app in simulator or in a real device;
  • Analyse all requirements for submit an app in store;
  • Analyse the common issues in store certification;
  • Fixe any issue found in the above steps;
  • Take screenshots for submit in the store;
  • Associate the app with the Store;
  • Generate the packages;
  • Validate the package with Windows App Certification Kit;
  • Create the required artwork (logo and others images, if need)
  • Submit the package in Dev Center;
  • Fill all data about the app, like description and keywords, and define the category and age rating;
  • Add up to 8 screenshots;

Now, let’s see it in more detail.

Test the app

After the application is created each developer should test the application in simulator or in real devices, in some cases is good to test the app in different devices with different characteristics (but is not required!).

The following articles will help to run the app in simulator or in devices

For Windows AppStudio apps is recommended to see the following video for help in the sideloading process: Generating, Sideloading, and Publishing Windows App Studio 8.1 apps for Tablets and PCs.

Sometimes couldn´t be easy to test our application or we don´t know what to test, a simple and good test is to provide the package to our friends or beta testers for they provide a feedback about the app, normally they saw issues that the developer not see. But before it, is recommended that each developer should do the basic tests provided in the following article Testing apps for Windows Phone 8.

In the article Testing apps for Windows Phone 8, we can find the App certification requirements for Windows Phone that are very important! If our app not respect this requirements the application will fail the certification and we should be updated about the changes in these requirements, for see the last changes read the article the App certification requirements change history for Windows Phone and finally we could read the Top Windows Phone app certification failures and how to avoid them. For Windows apps, you should read App certification requirements for the Windows Store and the common certification failures.

Each issue we find based in tests should be fixed and a new version should be created for apply new tests. After the app looks great you can skip to next step.

Take the screenshots

The next step is to take the screenshots that are required and this screenshots will showed to the user, and we only can upload up to 8 screenshots. For take the screenshots we can use the simulator, because it has a great feature for it, we only need to deploy the app in simulator as following

When we click in “Capture” button, the screenshot is taken and the image is save in a folder we defined.

Associate the app with the Store and generate packages

We can associate the app to the store and for it there are two ways: associate in Windows AppStudio or associate in Visual Studio.

In Windows AppStudio

The last step before generate the app (in Windows AppStudio) is the Publish, where the user can define the app title, the app description, the language, allow to connect the app with the store. The following screen show the Publish separator

In Publish separator (we saw above), click in “Associate App with the Store”, it will show the following form

For fill this form, we should open the Dashboard in Windows Phone Dev Center or in Windows Dev Center for get the information about our account (Publisher GUID, Publisher name)

And in the Dashboard we will find the Account option.

The information about the Menu App (App identity and App display name) is got after we create the application in dashboard, by clicking in Submit App.

Then we will have

At the end, we will have

After save all, it’s time to generate the app, for it, click in finish and then Generate. Now we need to choose Publish Packages, for create the packages for the store

After it we will get

At this moment we have the packages for the store.

In Visual Studio

For how that modified the app in Visual Studio or got the source code from in Windows AppStudio, is possible to connect the app with the Store, by doing

And then need to follow the wizard

At the end we will have an xml file with the store information, like following

 

After it is possible to generate the packages, as following

 

And we will get another wizard where we can choose if the package will be for store, and at the end we can set the package version, the output folder and others

In this cases, the packages are created for submit in store and the last panel will show the output path for the package and an option for run the Windows App Certification Kit

Running Windows App Certification Kit

If we click for “Launch Windows App Certification Kit” we will see the following wizard

Windows App Certification Kit is an automatic process for verify if the app is ok and it allow to select which test we want to run, in general, we should select all!

At the end, it will show the result, if passed or not and provide a report with more details. See the complete report here: MenuApp-WindowsAppCertificationKit-Report. If the app do not passe these tests, we should not submit the app in store until the issues reported in report are not fixed.

Note: One app that passed in this test can fail in others tests that this test do not test, but if the app not passed in these tests will not pass in store, too. For get more information about it, see the article Using the Windows App Certification Kit.

The artwork

Before go to the Dev Center for submit the app, we should prepare all artwork. The screenshots are taken, the app title icon with 300×300 should be created and if need create the background image with 1000×800, square icon with 358×358 and wide icon with 358×173.

Is recommended to see this App submission checklist which help to prepare and organize all the required info.

Uploading packages

Now is time to upload the package and fill the required data (description, keywords,…)

Choose the option 2, click “add new” and then choose the package

It will be uploaded and will showed the package name, version, package details

A form for description, keywords

 

And the options for add the artwork

Note:

  1. This form need to be defined for each language supported.
  2. If for some reason you get any issue when upload the packages, see the article Resolving package upload errors.

At this moment all data was filled and the app can be submitted to the certification process. If there is question about the certification process, and the different stages, we can find detailed info here.

In some cases, can be useful to add some notes to the testers (from certification process), for see how we should do it see the article Providing info to certification testers.

Now the sky is the limit and our app can be one of the top apps


For it we should promote our app, see more about in this article How to Market and Promote your apps on Windows Phone and Windows 8.

See also

[TechNet Wiki] The Microsoft TechNet Guru Awards! (September 2014) …. is out!

Yesterday was published the The Microsoft TechNet Guru Awards! (September 2014) and one more time I participated in TechNet Wiki. This time I published some articles about Azure Mobile Service and Windows AppStudio, which articles are related with Menu App, see all about it in Menu App Sample.

The results are good and I won

  • Microsoft Azure Technical Guru – September 2014 
  • Windows Phone and Windows Store Apps Technical Guru – September 2014 

Here are the boards

techinal guru

 

technical guru

How to binding a ResourceDictionary to a Lisbox in apps based in XAML

Scope

This sample as the goal to show how to binding a ResourceDictionary to a Lisbox in apps based in XAML, using the MVVM pattern.

Description

Suppose we have a resource dictionary with some data that we need to show in an application and for each item in listbox we want to show the key/value.

We will start by create a model class called “Company” that has only two properties: Name and Url.

    /// <summary>
    /// Define the Company.
    /// </summary>
    public class Company
    {
        /// <summary>
        /// Gets or sets the name.
        /// </summary>
        /// <value>The name.</value>
        public string Name { get; set; }

        /// <summary>
        /// Gets or sets the URL.
        /// </summary>
        /// <value>The URL.</value>
        public string Url { get; set; }
    }

In the MainViewModel we will create the resource dictionary where the Company is the key and the value will be an int, and we will have a SelectedCompany property for get the company selected in listbox.

The MainViewModel will be defined by

  public class MainViewModel : ViewModelBase
    {
        private Company _selectedCompany;

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            Companies = new Dictionary<Company, int>
            {
                {
                    new Company
                    {
                        Name = "Microsoft", Url="www.microsoft.com"
                    }, 1
                },
                {
                    new Company
                    {
                        Name = "Google", Url="www.google.com"
                    }, 2
                },
                {
                    new Company
                    {
                        Name = "Apple", Url="www.apple.com"
                    }, 3
                }
            };
        }

        /// <summary>
        /// Gets or sets the selected company.
        /// </summary>
        /// <value>The selected company.</value>
        public Company SelectedCompany
        {
            get { return _selectedCompany; }
            set { Set(() => SelectedCompany, ref _selectedCompany, value); }
        }

        /// <summary>
        /// Gets or sets the companies.
        /// </summary>
        /// <value>The companies.</value>
        public Dictionary<Company, int> Companies { get; set; }
    }

 

The MainWindow will defined as following

<mui:ModernWindow x:Class="BindingResourceDictionarySample.MainWindow"
                  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                  xmlns:mui="http://firstfloorsoftware.com/ModernUI"
                  Title="Sample"
                  Width="525"
                  Height="350"
                  DataContext="{Binding Main,
                                        Source={StaticResource Locator}}"
                  Style="{StaticResource BlankWindow}">
    <StackPanel>
        <TextBlock Margin="20,20,0,0" Text="How to binding a Dictionary to a Listbox" />
        <ListBox Width="250"
                 Margin="20,20,0,0"
                 HorizontalAlignment="Left"
                 ItemsSource="{Binding Companies}"
                 SelectedValue="{Binding ItemIndex}"
                 SelectedValuePath="Key"
                 SelectionMode="Single">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border Width="245"
                            BorderBrush="Orange"
                            BorderThickness="2">
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Margin="20,0,0,0" Text="{Binding Path=Value}" />
                            <TextBlock Margin="20,0,0,0" Text="{Binding Path=Key.Name}" />
                        </StackPanel>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>
</mui:ModernWindow>
For get the selected Company was used the SelectedValue property from Listbox, which will used the SelectedValuePath for know wich value will return. For get the value instead of Company we should change Key to Value.
Note:
1. For have a nice look, was used the ModernWindow from the ModernUI (for WPF). For see more about ModerUI see the following Modern UI Samples.
 2. The sample is similar for any XAML app, where we show the UI for WPF.

Running the sample

sample

Source Code Files

  • ViewModelLocator class contains static references to all the view model in  application and provides an entry point for the bindings.
  • MainViewModel class for binding to MainView.xaml
  • MainWindow represents the view.
  • Company defines the model.

Source

The source code can be find in MSDN Samples.

More Information

Ask me on twitter @saramgsilva

Follow me

My blog: typeof(saramgsilva)

My twitter @saramgsilva

 

[Survey] Developer tools (F12) – Customer feedback

ie

 Here’s your chance to voice your opinions about which areas of the tools you’re enjoying and what could be improved to make your IE workflow better, faster, and easier.

To show our thanks, we’re giving an Xbox One gaming console to one lucky participant. Make sure you give us your email address on the last page of the survey to enter the drawing!

Continue…

 

Modern UI for WPF application by example ( NavigationService – MVVM )

Scope

This article has the goal to show how to create a navigation service for WPF application that uses Modern UI.

Introduction

Modern UI is a set of controls and styles converting our WPF application into a great looking Modern UI app. The Modern UI project can be find in mui.codeplex.com, here is possible to get the WPF app that demostrate the features provided by “mui”.

WPF don´t have a pattern for the navigation when we are using Windows, only exist a navigation service when we use Pages. ModernUI introduce a special way for the navigation, that use the ModernFrame.

For the sample we will use MVVMLight Toolkit for help in the MVVM pattern implementation and we will use a new feature provided by this toolkit, the INavigationService interface.

Note: The MVVMLight Toolkit don´t have any implementation of INavigationService for WPF, for see more about it read this article  Announcing MVVM Light V5 for Windows and Xamarin.

 Description

The source code base, that we will used in this sample, is similar to the sample used in the article Modern UI for WPF application by example (Default Window).

We will start to create the interface IModernNavigationService and the NavigationService, after it we will configure the navigation in MainWindow and then wil use the navigation service in the view model for navigate to another view.

The interface will be something like

    public interface IModernNavigationService : INavigationService
    {
        /// <summary>
        /// Gets the parameter.
        /// </summary>
        /// <value>
        /// The parameter.
        /// </value>
        object Parameter { get; }
    }

which implementation will be

    public class NavigationService : IModernNavigationService
    {
        private readonly Dictionary<string, Uri> _pagesByKey;
        private readonly List<string> _historic;
 
        /// <summary>
        /// Initializes a new instance of the <see cref="NavigationService"/> class.
        /// </summary>
        public NavigationService()
        {
            _pagesByKey = new Dictionary<string, Uri>();
            _historic = new List<string>();
        }

        /// <summary>
        /// Gets the key corresponding to the currently displayed page.
        /// </summary>
        /// <value>
        /// The current page key.
        /// </value>
        public string CurrentPageKey
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the parameter.
        /// </summary>
        /// <value>
        /// The parameter.
        /// </value>
        public object Parameter { get; private set; }

        /// <summary>
        /// The go back.
        /// </summary>
        public void GoBack()
        {
            if (_historic.Count > 1)
            {
                _historic.RemoveAt(_historic.Count - 1);
                NavigateTo(_historic.Last(), null);
            }
        }

        /// <summary>
        /// The navigate to.
        /// </summary>
        /// <param name="pageKey">
        /// The page key.
        /// </param>
        public void NavigateTo(string pageKey)
        {
            NavigateTo(pageKey, null);
        }

        /// <summary>
        /// The navigate to.
        /// </summary>
        /// <param name="pageKey">
        /// The page key.
        /// </param>
        /// <param name="parameter">
        /// The parameter.
        /// </param>
        public virtual void NavigateTo(string pageKey, object parameter)
        {
            lock (_pagesByKey)
            {
                if (!_pagesByKey.ContainsKey(pageKey))
                {
                    throw new ArgumentException(string.Format("No such page: {0}. Did you forget to call NavigationService.Configure?", pageKey), "pageKey");
                }

                var frame = GetDescendantFromName(Application.Current.MainWindow, "ContentFrame") as ModernFrame;

                // Set the frame source, which initiates navigation
                if (frame != null)
                {
                    frame.Source = _pagesByKey[pageKey];
                }
                Parameter = parameter;
                _historic.Add(pageKey);
                CurrentPageKey = pageKey;
            }
        }

        /// <summary>
        /// Configures the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="pageType">Type of the page.</param>
        public void Configure(string key, Uri pageType)
        {
            lock (_pagesByKey)
            {
                if (_pagesByKey.ContainsKey(key))
                {
                    _pagesByKey[key] = pageType;
                }
                else
                {
                    _pagesByKey.Add(key, pageType);
                }
            }
        }

        /// <summary>
        /// Gets the name of the descendant from.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="name">The name.</param>
        /// <returns>The FrameworkElement.</returns>
        private static FrameworkElement GetDescendantFromName(DependencyObject parent, string name)
        {
            var count = VisualTreeHelper.GetChildrenCount(parent);

            if (count < 1)
            {
                return null;
            }

            for (var i = 0; i < count; i++)
            {
                var frameworkElement = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
                if (frameworkElement != null)
                {
                    if (frameworkElement.Name == name)
                    {
                        return frameworkElement;
                    }

                    frameworkElement = GetDescendantFromName(frameworkElement, name);
                    if (frameworkElement != null)
                    {
                        return frameworkElement;
                    }
                }
            }

            return null;
        }
    }

and the setup for the navigation will be done in the MainWindow.xaml.cs, something like

        private void SetupNavigation()
        {
            var navigationService = new NavigationService();
            navigationService.Configure(ViewModelLocator.ResourcePageKey, new Uri("Views/ResourcesView.xaml"));
            navigationService.Configure(ViewModelLocator.StepsPageKey, new Uri("Views/StepsView.xaml"));

            SimpleIoc.Default.Register<IModernNavigationService>(() => navigationService);
        }

 

In the StepsViewModel we will do

 

    public class StepsViewModel : ViewModelBase
    {
        private readonly IModernNavigationService _modernNavigationService;

        /// <summary>
        /// Initializes a new instance of the <see cref="StepsViewModel"/> class. 
        /// </summary>
        /// <param name="modernNavigationService">
        /// The modern Navigation Service.
        /// </param>
        public StepsViewModel(IModernNavigationService modernNavigationService)
        {
            _modernNavigationService = modernNavigationService;
            ResourcesCommand = new RelayCommand(ShowResources);
        }

        /// <summary>
        /// Gets or sets the resources command.
        /// </summary>
        /// <value>The resources command.</value>
        public ICommand ResourcesCommand { get; set; }

        /// <summary>
        /// Shows the resources.
        /// </summary>
        private void ShowResources()
        {
            _modernNavigationService.NavigateTo(ViewModelLocator.ResourcePageKey);
        }
    }

 

Note:

1. For send a parameter when navigate we should do

 _modernNavigationService.NavigateTo(ViewModelLocator.ResourcePageKey, myParameterValue);

and then in the view model use the Parameter property, from the navigation service, for get the parameter

     _modernNavigationService.Parameter

2. For navigate to the preview page use the GoBack method

 _modernNavigationService.GoBack();

Source code

Get the source code for this sample in github.

 

Visual Studio extension used

resharper    ghostdoc  stylecop

Modern UI for WPF application by example ( NavigationMessageService – MVVM )

Scope

This article has the goal to show how to create a navigation mensage service for WPF application that uses Modern UI.

Introduction

Modern UI is a set of controls and styles converting our WPF application into a great looking Modern UI app. The Modern UI project can be find in mui.codeplex.com, here is possible to get the WPF app that demostrate the features provided by “mui”.

WPF don´t have a pattern for the navigation when we are using Windows, only exist a navigation service for Pages. ModernUI introduce a special way for the navigation, that use the ModernFrame.

In the article  Modern UI for WPF application by example (Handle Navigation: (Default)) we saw how to handle the navigation. In this sample we will see how to navigate between views using messages.

Description

The navigation we will implement is based in messages send from a view model to the MainWindow, these messages are send/received by Messenger class provided by MVVMLight Toolkit.

Start by create the NavigationMessage as following

    public class NavigationMessage
    {
        /// <summary>
        /// Gets or sets the page.
        /// </summary>
        /// <value>The page.</value>
        public string Page { get; set; }
    }

In the MainWindow register for receive the message defined as following

        private void RegisterNavigation()
        {
            Messenger.Default.Register<NavigationMessage>(this, p =>
            {
                var frame = GetDescendantFromName(this, "ContentFrame") as ModernFrame;
                 
                // Set the frame source, which initiates navigation
                if (frame != null)
                {
                    frame.Source = new Uri(p.Page, UriKind.Relative);
                }
            });
        }

Where GetDescendantFromName is the method that use VisualTreeHelper for get the ModernFrame.

In the StepsViewModel send the NavigationMessage with the path for the view we wants to navigate

        private void ShowResources()
        {
            Messenger.Default.Send(new NavigationMessage()
            {
                Page = "Views/ResourcesControl.xaml"
            }); 
        }

 

Where we only navigated to the new view, for send parameters when navigate we should use another message with the parameter we want to send, with it the comunication will we between view models.

 

Source code

Get the source code for this sample in github.

 

Visual Studio extension used

resharper    ghostdoc  stylecop

Modern UI for WPF application by example (Handle Navigation)

Scope

This article has the goal to show how to create a blank window in WPF using Modern UI, which handle the navigation.

Introduction

Modern UI is a set of controls and styles converting our WPF application into a great looking Modern UI app. The Modern UI project can be find in mui.codeplex.com, here is possible to get the WPF app that demostrate the features provided by “mui”.

WPF don´t have a pattern for the navigation when we are using Windows, only exist a navigation service when we use Pages. ModernUI introduce a special way for the navigation, that use the ModernFrame.

The question here is, how I know when the user is navigating from one view to another?

 

Description

In the sample Modern UI for WPF application by example (Default Window) we saw the default window provided by Modern UI, and in this sample we will use the same base code but we will change the code for handle the navigation.

If we search the properties from the  ModernWindow, we will see that it don´t have any event or method for handle navigation. After some search in documentation, we find an article Handle navigation events in your content.

Let’s apply it!

The MainWindow contains a MenuLinkGroups which contains a LinkGroup with two Links. Each link is defined by a UserControl. For handle navigation, each user control will implement the interface IContent, like following

    /// <summary>
    /// Interaction logic for StepsControl.xaml.
    /// </summary>
    public partial class StepsControl : IContent
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="StepsControl"/> class.
        /// </summary>
        public StepsControl()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Called when navigation to a content fragment begins.
        /// </summary>
        /// <param name="e">An object that contains the navigation data.</param>
        public void OnFragmentNavigation(FragmentNavigationEventArgs e)
        {
            Debug.WriteLine("StepsControl- OnFragmentNavigation");
        }

        /// <summary>
        /// Called when this instance is no longer the active content in a frame.
        /// </summary>
        /// <param name="e">An object that contains the navigation data.</param>
        public void OnNavigatedFrom(NavigationEventArgs e)
        {
            Debug.WriteLine("StepsControl -OnNavigatedFrom");
        }

        /// <summary>
        /// Called when a this instance becomes the active content in a frame.
        /// </summary>
        /// <param name="e">An object that contains the navigation data.</param>
        public void OnNavigatedTo(NavigationEventArgs e)
        {
            Debug.WriteLine("StepsControl- OnNavigatedTo");
        }

        /// <summary>
        /// Called just before this instance is no longer the active content in a frame.
        /// </summary>
        /// <param name="e">
        /// An object that contains the navigation data.
        /// </param>
        /// <remarks>
        /// The method is also invoked when parent frames are about to navigate.
        /// </remarks>
        public void OnNavigatingFrom(NavigatingCancelEventArgs e)
        {
            Debug.WriteLine("StepsControl- OnNavigatingFrom");
        }
    }

Using Debug.WriteLine we will show in output window the flow when we navigate in MainWindow.

The output will be something like

StepsControl - OnNavigatedTo
StepsControl - OnNavigatingFrom
StepsControl - OnNavigatedFrom
ResourcesControl - OnNavigatedTo
ResourcesControl - OnNavigatingFrom
ResourcesControl - OnNavigatedFrom
StepsControl - OnNavigatedTo
StepsControl - OnNavigatingFrom
StepsControl - OnNavigatedFrom
ResourcesControl - OnNavigatedTo

See the code source in github – ModernUIForWPFSample.Navigation (Default) .

Suppose when we navigate we want to do some task and we are using the  MVVM pattern. We could get the view model defined in DataContext and then call method that apply what we want, something like

        public void OnNavigatedTo(NavigationEventArgs e)
        {
            var viewModel = DataContext as MyViewModel;
            if (viewModel != null)
            {
                viewModel.DoSomething();
            }
        }

 

or we can define events that will be called when the methods from IContent are raised and this events can be defined in UI using the EventTrigger and InvokeCommandAction. With this we will avoid code in code behiden.

First we will create our ModernUserControl which is a UserControl and implements the IContent. This control will have four events, one for each method required for IContent.

The implementation will be something like

    public class ModernUserControl : UserControl, IContent
    {
        /// <summary>
        /// Handles the <see cref="E:FragmentNavigation"/> event.
        /// </summary>
        /// <param name="e">The <see cref="FirstFloor.ModernUI.Windows.Navigation.FragmentNavigationEventArgs"/> instance containing the event data.</param>
        public void OnFragmentNavigation(FragmentNavigationEventArgs e)
        {
            if (FragmentNavigation != null)
            {
                FragmentNavigation(this, e);
            }
        }

        /// <summary>
        /// Handles the <see cref="E:NavigatedFrom"/> event.
        /// </summary>
        /// <param name="e">The <see cref="FirstFloor.ModernUI.Windows.Navigation.NavigationEventArgs"/> instance containing the event data.</param>
        public void OnNavigatedFrom(NavigationEventArgs e)
        {
            if (NavigatedFrom != null)
            {
                NavigatedFrom(this, e);
            }
        }

        /// <summary>
        /// Handles the <see cref="E:NavigatedTo"/> event.
        /// </summary>
        /// <param name="e">The <see cref="FirstFloor.ModernUI.Windows.Navigation.NavigationEventArgs"/> instance containing the event data.</param>
        public void OnNavigatedTo(NavigationEventArgs e)
        {
            if (NavigatedTo != null)
            {
                NavigatedTo(this, e);
			}
        }

        /// <summary>
        /// Handles the <see cref="E:NavigatingFrom"/> event.
        /// </summary>
        /// <param name="e">The <see cref="FirstFloor.ModernUI.Windows.Navigation.NavigatingCancelEventArgs"/> instance containing the event data.</param>
        public void OnNavigatingFrom(NavigatingCancelEventArgs e)
        {
            if (NavigatingFrom != null)
            {
                NavigatingFrom(this, e);
            }
        }

        /// <summary>
        /// Occurs when [navigating from].
        /// </summary>
        public event NavigatingCancelHandler NavigatingFrom;

        /// <summary>
        /// Occurs when [navigated from].
        /// </summary>
        public event NavigationEventHandler NavigatedFrom;

        /// <summary>
        /// Occurs when [navigated to].
        /// </summary>
        public event NavigationEventHandler NavigatedTo;

        /// <summary>
        /// Occurs when [fragment navigation].
        /// </summary>
        public event FragmentNavigationHandler FragmentNavigation;
    }

 

After it, StepsUserControl and ResourcesUserControl will be a ModernUserControl has following

<controls:ModernUserControl x:Class="ModernUIForWPFSample.Navigation.Views.StepsControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:controls="clr-namespace:ModernUIForWPFSample.Navigation__MVVM_.Controls"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             d:DesignHeight="300"
             d:DesignWidth="600" 
             mc:Ignorable="d" 
             DataContext="{Binding StepsViewModel, Source={StaticResource Locator}}">
    <i:Interaction.Triggers>
         <i:EventTrigger EventName="NavigatedTo">
            <i:InvokeCommandAction Command="{Binding NavigatedToCommand}" />
        </i:EventTrigger>
        <i:EventTrigger EventName="NavigatedFrom">
            <i:InvokeCommandAction Command="{Binding NavigatedFromCommand}" />
        </i:EventTrigger>
        <i:EventTrigger EventName="NavigatingFrom">
            <i:InvokeCommandAction Command="{Binding NavigatingFromCommand}" />
        </i:EventTrigger>
        <i:EventTrigger EventName="FragmentNavigation">
            <i:InvokeCommandAction Command="{Binding FragmentNavigationCommand}" />
        </i:EventTrigger>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding LoadedCommand}" />
        </i:EventTrigger>
        <i:EventTrigger EventName="IsVisibleChanged">
            <i:InvokeCommandAction Command="{Binding IsVisibleChangedCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <Grid>
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap">
            Steps:
            <LineBreak />
            1st Install the ModernUI from Nuget
            <LineBreak />
            2nd Define in App.xaml the resources for ModernUI.xaml and ModernUI.Light.xaml
            <LineBreak />
            3rd Change the MainWindow: Replace the tag &quot;Window&quot; to ModernWindow
            <LineBreak />
            4th Define the content for the MainWindow using TitleLinks, MenuLinkGroups, LinkGroup...
            <LineBreak />
            5th Define which content is shown when the application start, by using the ContentSource
            <LineBreak />
            6th For each content (in this case for StepsControl and ResourcesControl) must implement the interface IContent 
            <LineBreak />
            7th For each navigation method (OnFragmentNavigation, OnNavigatedFrom, OnNavigatedTo and OnNavigatingFrom) add the behavior you want
            <LineBreak />
            <LineBreak />
            Note: For change the appearance use  AppearanceManager class
        </TextBlock>
    </Grid>
</controls:ModernUserControl>

 

For help in th MVVM pattern implementation we will use MVVMLight Toolkit and we will have two view models (StepsViewModel and ResourcesViewModel). Here are the class diagram.

ViewModelLocator will help in binding the view model to the view and is where we setup the dependencies when we use dependency injection.

When we ran the application the output will be something like

ModernUserControl - OnNavigatedTo
StepsViewModel - LoadData
ModernUserControl - OnNavigatingFrom
StepsViewModel - NavigatingFrom
ModernUserControl - OnNavigatingFrom event called
ModernUserControl - OnNavigatedFrom
StepsViewModel - NavigatedFrom
ModernUserControl - OnNavigatedFrom event called
ModernUserControl - OnNavigatedTo
StepsViewModel - LoadData
ResourcesViewModel - LoadData
ModernUserControl - OnNavigatingFrom
ResourcesViewModel - NavigatingFrom
ModernUserControl - OnNavigatingFrom event called
ModernUserControl - OnNavigatedFrom
ResourcesViewModel - NavigatedFrom
ModernUserControl - OnNavigatedFrom event called
ModernUserControl - OnNavigatedTo
StepsViewModel - NavigatedTo
ModernUserControl - OnNavigatedTo event called
ResourcesViewModel - LoadData
StepsViewModel - LoadData

With it, we can conclude when we use events, the NavigateTo event is not raised at the first time the control is shown, it because the NavigateTo event wasn´t subscrived when the first navigation occurs.

See others solutions for Navigation in ModernUI applications.

Modern UI for WPF application by example ( NavigationMessageService – MVVM )

Modern UI for WPF application by example ( NavigationService – MVVM )

Source code

Get the source code for this sample in github.

 

Visual Studio extension used

resharper    ghostdoc      stylecop

How to send data through bluetooth in a WPF application using 32feet.Net

Scope

This article has the goal to show a solution for send data between devices using a WPF application and the library 32feet.Net.

The solution will implement the MVVM pattern and will use the MVVMLight Toolkit.

Introduction

Bluetooth is an industry-standard protocol that enables wireless connectivity for computers, handheld devices, mobile phones, and other devices.

Bluetooth is designed for use by C/C++ programmers. Some Bluetooth features are available with Windows Sockets. Familiarity with Microsoft Windows networking and Windows Sockets programming is required. The article Bluetooth Programming with Windows Sockets, describes how to use Windows Sockets functions and structures to program a Bluetooth application and provide the Bluetooth connection sample. But in a first attempt it not looks so nice, when our goal is to create a WPF application.

In Codeplex, there is a project called 32feet.NET. This project is a shared-source project to make personal area networking technologies such as Bluetooth, Infrared (IrDA) and more, easily accessible from .NET code. Supports desktop, mobile or embedded systems.

32feet.NET is available on Nuget, and for desktop apps the reference is this 32feet.NET 3.5.0 Nuget Package. Which version we will use in the sample we will create.

Description

The WPF Application will have two “modes”: Sender and Receiver. Where the “Sender” has the responsibility to send messages and the “Receiver” will get the messages sent by “Sender”.

Let’s start!

Creating the project

First create the WPF application in Visual Studio

 After it, install the nugget packages: MVVMLight and 32feet.Net, as following

Installing MVVM Light Toolkit

Installing 32feet.Net

At the end our solution will have the base structure for implement MVVM, that MVVM Light installed through the nuget.

Now we need to define the model for the device that is required when we get the list of the devices around us with bluetooth on.

The Model

The model is defined by the Device class that represent the structure for the device around us. The implementation is

 public sealed class Device
    {
        /// <summary>
        /// Gets or sets the device name.
        /// </summary>
        /// <value>
        /// The device name.
        /// </value>
        public string DeviceName { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether authenticated.
        /// </summary>
        /// <value>
        /// The authenticated.
        /// </value>
        public bool IsAuthenticated { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether is connected.
        /// </summary>
        /// <value>
        /// The is connected.
        /// </value>
        public bool IsConnected { get; set; }

        /// <summary>
        /// Gets or sets the nap.
        /// </summary>
        /// <value>
        /// The nap.
        /// </value>
        public ushort Nap { get; set; }

        /// <summary>
        /// Gets or sets the sap.
        /// </summary>
        /// <value>
        /// The sap.
        /// </value>
        public uint Sap { get; set; }

        /// <summary>
        /// Gets or sets the last seen.
        /// </summary>
        /// <value>
        /// The last seen.
        /// </value>
        public DateTime LastSeen { get; set; }

        /// <summary>
        /// Gets or sets the last used.
        /// </summary>
        /// <value>
        /// The last used.
        /// </value>
        public DateTime LastUsed { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether remembered.
        /// </summary>
        /// <value>
        /// The remembered.
        /// </value>
        public bool Remembered { get; set; }
        
        /// <summary>
        /// Gets or sets the device info.
        /// </summary>
        /// <value>
        /// The device info.
        /// </value>
        public BluetoothDeviceInfo DeviceInfo { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="Device"/> class.
        /// </summary>
        /// <param name="device_info">
        /// The device_info.
        /// </param>
        public Device(BluetoothDeviceInfo device_info)
        {
            if (device_info != null)
            {
                DeviceInfo = device_info;
                IsAuthenticated = device_info.Authenticated;
                IsConnected = device_info.Connected;
                DeviceName = device_info.DeviceName;
                LastSeen = device_info.LastSeen;
                LastUsed = device_info.LastUsed;
                Nap = device_info.DeviceAddress.Nap;
                Sap = device_info.DeviceAddress.Sap;
                Remembered = device_info.Remembered;
            }
        }

        /// <summary>
        /// The to string.
        /// </summary>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public override string ToString()
        {
            return DeviceName;
        }
    }

In a class diagram we will have

The Services

The services in the application will define the features for the “Sender” and for the “Receiver”. These classes will be injected to the view model using the ServiceLocator, and the setup is defined in the ViewModelLocator constructor.

For “Sender” and “Receiver” are connected each other, we need to define a Guid that is set to the ServiceClassId and it is the key for the communication. When “Sender” send a message using the ServiceClassID X only the “Receiver” that know the ServiceClassID X will get the data, any other “Receiver” that know only the ServiceClassID Y, for exemple, will not receive the data.

 The ReceiverBluetoothService

The ReceiverBluetoothService define how the “Receiver” will receive the data from the “Sender”. For it is used a thread that will run and will be listening by data.

The implementation for this class is something like

 

   public class ReceiverBluetoothService : ObservableObject, IDisposable, IReceiverBluetoothService
    {
        private readonly Guid _serviceClassId;
        private Action<string> _responseAction;
        private BluetoothListener _listener;
        private CancellationTokenSource _cancelSource;
        private bool _wasStarted;
        private string _status;

        /// <summary>
        /// Initializes a new instance of the <see cref="ReceiverBluetoothService" /> class.
        /// </summary>
        public ReceiverBluetoothService()
        {
           _serviceClassId = new Guid("0e6114d0-8a2e-477a-8502-298d1ff4b4ba");
        }

        /// <summary>
        /// Gets or sets a value indicating whether was started.
        /// </summary>
        /// <value>
        /// The was started.
        /// </value>
        public bool WasStarted
        {
            get { return _wasStarted; }
            set { Set(() => WasStarted, ref _wasStarted, value); }
        }
        
        /// <summary>
        /// Starts the listening from Senders.
        /// </summary>
        /// <param name="reportAction">
        /// The report Action.
        /// </param>
        public void Start(Action<string> reportAction)
        {
            WasStarted = true;
            _responseAction = reportAction;
            if (_cancelSource != null && _listener != null)
            {
                Dispose(true);
            }
            _listener = new BluetoothListener(_serviceClassId)
            {
                ServiceName = "MyService"
            };
            _listener.Start();

            _cancelSource = new CancellationTokenSource();

            Task.Run(() => Listener(_cancelSource));
        }

        /// <summary>
        /// Stops the listening from Senders.
        /// </summary>
        public void Stop()
        {
            WasStarted = false;
            _cancelSource.Cancel();
        }

        /// <summary>
        /// Listeners the accept bluetooth client.
        /// </summary>
        /// <param name="token">
        /// The token.
        /// </param>
        private void Listener(CancellationTokenSource token)
        {
            try
            {
                while (true)
                {
                    using (var client = _listener.AcceptBluetoothClient())
                    {
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }

                        using (var streamReader = new StreamReader(client.GetStream()))
                        {
                            try
                            {
                                var content = streamReader.ReadToEnd();
                                if (!string.IsNullOrEmpty(content))
                                {
                                    _responseAction(content);
                                }
                            }
                            catch (IOException)
                            {
                                client.Close();
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception exception)
            {
               // todo handle the exception
               // for the sample it will be ignored
            }
        }

        /// <summary>
        /// The dispose.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// The dispose.
        /// </summary>
        /// <param name="disposing">
        /// The disposing.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_cancelSource != null)
                {
                    _listener.Stop();
                    _listener = null;
                    _cancelSource.Dispose();
                    _cancelSource = null;
                }
            }
        }
    }

In the Start method we need to define an action that will be used for report the data received in ViewModel. We could use an event or the Message feature from MVVMLight.

In the Listener method that is running in another thread, we defined a CancellationTokenSource that will be used for stop the process for listening for data.

Note: The “Receiver” allow to start or stop the process for listening data. If a “Sender” send data but the “Receiver” not allow listening, the “Sender” will send the data but “Receiver” will not get it.

The SenderBluetoothService

The SenderBluetoothService define how the “Sender” will send data, but for it is required to select a device that is available. Is not possible to filter for devices that knows the ServiceClassId and the name of the device for where the “Sender” wants to send the data should be known.

The implementation for this class is something like

  public sealed class SenderBluetoothService : ISenderBluetoothService
    {
         private readonly Guid _serviceClassId;

        /// <summary>
        /// Initializes a new instance of the <see cref="SenderBluetoothService"/> class. 
        /// </summary>
        public SenderBluetoothService()
        {
            // this guid is random, only need to match in Sender & Receiver
            // this is like a "key" for the connection!
            _serviceClassId = new Guid("0e6114d0-8a2e-477a-8502-298d1ff4b4ba");
        }

        /// <summary>
        /// Gets the devices.
        /// </summary>
        /// <returns>The list of the devices.</returns>
        public async Task<IList<Device>> GetDevices()
        {
            // for not block the UI it will run in a different threat
            var task = Task.Run(() =>
            {
                var devices = new List<Device>();
                using (var bluetoothClient = new BluetoothClient())
                {
                    var array = bluetoothClient.DiscoverDevices();
                    var count = array.Length;
                    for (var i = 0; i < count; i++)
                    {
                        devices.Add(new Device(array[i]));
                    }
                }
                return devices;
            });
            return await task;
        }

        /// <summary>
        /// Sends the data to the Receiver.
        /// </summary>
        /// <param name="device">The device.</param>
        /// <param name="content">The content.</param>
        /// <returns>If was sent or not.</returns>
        public async Task<bool> Send(Device device, string content)
        {
            if (device == null)
            {
                throw new ArgumentNullException("device");
            }

            if (string.IsNullOrEmpty(content))
            {
                throw new ArgumentNullException("content");
            }

            // for not block the UI it will run in a different threat
            var task = Task.Run(() =>
            {
                using (var bluetoothClient = new BluetoothClient())
                {
                    try
                    {
                        var ep = new BluetoothEndPoint(device.DeviceInfo.DeviceAddress, _serviceClassId);
                       
                        // connecting
                        bluetoothClient.Connect(ep);

                        // get stream for send the data
                        var bluetoothStream = bluetoothClient.GetStream();

                        // if all is ok to send
                        if (bluetoothClient.Connected && bluetoothStream != null)
                        {
                            // write the data in the stream
                            var buffer = System.Text.Encoding.UTF8.GetBytes(content);
                            bluetoothStream.Write(buffer, 0, buffer.Length);
                            bluetoothStream.Flush();
                            bluetoothStream.Close();
                            return true;
                        }
                        return false;
                    }
                    catch
                    {
                        // the error will be ignored and the send data will report as not sent
                        // for understood the type of the error, handle the exception
                    }
                }
                return false;
            });
            return await task;
        }
    }

In the Send method, when we are connected to the selected device, we will be available to write in a stream which is received by “Receiver”.

The ViewModel

We will define the following view models: ReceiverViewModel, SenderViewModel and MainViewModel that will be binding to the DataContext in ReceiverView, SenderView and MainWindow respectively.

The ReceiverViewModel

The implementation will be something like

    public sealed class ReceiverViewModel : ViewModelBase
    {
        private readonly IReceiverBluetoothService _receiverBluetoothService;
        private string _data;
        private bool _isStarEnabled;
        private string _status;

        /// <summary>
        /// Initializes a new instance of the <see cref="ReceiverViewModel" /> class.
        /// </summary>
        /// <param name="receiverBluetoothService">The Receiver bluetooth service.</param>
        public ReceiverViewModel(IReceiverBluetoothService receiverBluetoothService)
        {
            _receiverBluetoothService = receiverBluetoothService;
            _receiverBluetoothService.PropertyChanged += ReceiverBluetoothService_PropertyChanged;
            IsStarEnabled = true;
            Data = "N/D";
            Status = "N/D";
            StartCommand = new RelayCommand(() =>
            {
                _receiverBluetoothService.Start(SetData);
                IsStarEnabled = false;
                Data = "Can receive data.";
            });

            StopCommand = new RelayCommand(() =>
            {
                _receiverBluetoothService.Stop();
                IsStarEnabled = true;
                Data = "Cannot receive data.";
            });

            Messenger.Default.Register<Message>(this, ResetAll);
        }

        /// <summary>
        /// Resets all.
        /// </summary>
        /// <param name="message">The message.</param>
        private void ResetAll(Message message)
        {
            if (!message.IsToShowDevices)
            {
                if (_receiverBluetoothService.WasStarted)
                {
                    _receiverBluetoothService.Stop();
                }
                IsStarEnabled = true;
                Data = "N/D";
                Status = "N/D";
            }
        }

        /// <summary>
        /// The set data received.
        /// </summary>
        /// <param name="data">
        /// The data.
        /// </param>
        public void SetData(string data)
        {
            Data = data;
        }

        /// <summary>
        /// Gets or sets the data.
        /// </summary>
        /// <value>
        /// The data received.
        /// </value>
        public string Data
        {
            get { return _data; }
            set { Set(() => Data, ref _data, value); }
        }

        /// <summary>
        /// Gets the start command.
        /// </summary>
        /// <value>
        /// The start command.
        /// </value>
        public ICommand StartCommand { get; private set; }

        /// <summary>
        /// Gets the stop command.
        /// </summary>
        /// <value>
        /// The stop command.
        /// </value>
        public ICommand StopCommand { get; private set; }

        /// <summary>
        /// Gets or sets a value indicating whether is star enabled.
        /// </summary>
        /// <value>
        /// The is star enabled.
        /// </value>
        public bool IsStarEnabled
        {
            get
            {
                return _isStarEnabled;
            }
            set
            {
                Set(() => IsStarEnabled, ref _isStarEnabled, value);
                RaisePropertyChanged(() => IsStopEnabled);
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether is stop enabled.
        /// </summary>
        /// <value>
        /// The is stop enabled.
        /// </value>
        public bool IsStopEnabled
        {
            get
            {
                return !_isStarEnabled;
            }
            set
            {
                Set(() => IsStopEnabled, ref _isStarEnabled, !value);
                RaisePropertyChanged(() => IsStarEnabled);
            }
        }

        /// <summary>
        /// Gets or sets the status.
        /// </summary>
        /// <value>The status.</value>
        public string Status
        {
            get { return _status; }
            set { Set(() => Status, ref _status, value); }
        }

        /// <summary>
        /// Handles the PropertyChanged event of the ReceiverBluetoothService control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.PropertyChangedEventArgs"/> instance containing the event data.</param>
        private void ReceiverBluetoothService_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "WasStarted")
            {
                IsStarEnabled = true;
            }
        }
    }

The SenderViewModel

The implementation will be something like

    public sealed class SenderViewModel : ViewModelBase
    {
        private readonly ISenderBluetoothService _senderBluetoothService;
        private string _data;
        private Device _selectDevice;
        private string _resultValue;

        /// <summary>
        /// Initializes a new instance of the <see cref="SenderViewModel"/> class.
        /// </summary>
        /// <param name="senderBluetoothService">
        /// The Sender bluetooth service.
        /// </param>
        public SenderViewModel(ISenderBluetoothService senderBluetoothService)
        {
            _senderBluetoothService = senderBluetoothService;
            ResultValue = "N/D";
            SendCommand = new RelayCommand(
                SendData,
                () => !string.IsNullOrEmpty(Data) && SelectDevice != null && SelectDevice.DeviceInfo != null);
            Devices = new ObservableCollection<Device>
            {
                new Device(null) { DeviceName = "Searching..." }
            };
            Messenger.Default.Register<Message>(this, ShowDevice);
        }

        /// <summary>
        /// Gets or sets the devices.
        /// </summary>
        /// <value>
        /// The devices.
        /// </value>
        public ObservableCollection<Device> Devices
        {
            get; set;
        }

        /// <summary>
        /// Gets or sets the select device.
        /// </summary>
        /// <value>
        /// The select device.
        /// </value>
        public Device SelectDevice
        {
            get { return _selectDevice; }
            set { Set(() => SelectDevice, ref _selectDevice, value); }
        }

        /// <summary>
        /// Gets or sets the data.
        /// </summary>
        /// <value>
        /// The data.
        /// </value>
        public string Data
        {
            get { return _data; }
            set { Set(() => Data, ref _data, value); }
        }

        /// <summary>
        /// Gets or sets the result value.
        /// </summary>
        /// <value>
        /// The result value.
        /// </value>
        public string ResultValue
        {
            get { return _resultValue; }
            set { Set(() => ResultValue, ref _resultValue, value); }
        }

        /// <summary>
        /// Gets the send command.
        /// </summary>
        /// <value>
        /// The send command.
        /// </value>
        public ICommand SendCommand { get; private set; }

        private async void SendData()
        {
            ResultValue = "N/D";
            var wasSent = await _senderBluetoothService.Send(SelectDevice, Data);
            if (wasSent)
            {
                ResultValue = "The data was sent.";
            }
            else
            {
                ResultValue = "The data was not sent.";
            }
        }

        /// <summary>
        /// Shows the device.
        /// </summary>
        /// <param name="deviceMessage">The device message.</param>
        private async void ShowDevice(Message deviceMessage)
        {
            if (deviceMessage.IsToShowDevices)
            {
                var items = await _senderBluetoothService.GetDevices();
                Devices.Clear();
                Devices.Add(items);
                Data = string.Empty;
            }
        }
    }

The MainViewModel

The implementation will be something like

public sealed class MainViewModel : ViewModelBase
    {
        private bool _isReceiver;

        /// <summary>
        /// Initializes a new instance of the <see cref="MainViewModel"/> class.
        /// </summary>
        public MainViewModel()
        {
            PropertyChanged += MainViewModelPropertyChanged;
            IsSender = false;
        }

        /// <summary>
        /// Gets or sets a value indicating whether is Receiver.
        /// </summary>
        /// <value>
        /// The is Receiver.
        /// </value>
        public bool IsReceiver
        {
            get
            {
                return _isReceiver;
            }
            set
            {
                Set(() => IsReceiver, ref _isReceiver, value);
                RaisePropertyChanged(() => IsSender);
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether is Sender.
        /// </summary>
        /// <value>
        /// The is Sender.
        /// </value>
        public bool IsSender
        {
            get
            {
                return !_isReceiver;
            }
            set
            {
                Set(() => IsSender, ref _isReceiver, !value);
                RaisePropertyChanged(() => IsReceiver);
            }
        }

        /// <summary>
        /// Gets or sets the Receiver visibility.
        /// </summary>
        /// <value>
        /// The Receiver visibility.
        /// </value>
        public Visibility ReceiverVisibility
        {
            get
            {
                return _isReceiver ? Visibility.Visible : Visibility.Collapsed;
            }
            set
            {
                _isReceiver = value == Visibility.Visible;
            }
        }

        /// <summary>
        /// Gets or sets the Sender visibility.
        /// </summary>
        /// <value>
        /// The Sender visibility.
        /// </value>
        public Visibility SenderVisibility
        {
            get
            {
                return !_isReceiver ? Visibility.Visible : Visibility.Collapsed;
            }
            set 
            {
                _isReceiver = value != Visibility.Visible;
            }
        }

        /// <summary>
        /// Mains the view model property changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.ComponentModel.PropertyChangedEventArgs"/> instance containing the event data.</param>
        private void MainViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsReceiver" || e.PropertyName == "IsSender")
            {
                RaisePropertyChanged(() => ReceiverVisibility);            
                RaisePropertyChanged(() => SenderVisibility);

                if (e.PropertyName == "IsReceiver")
                {
                    Messenger.Default.Send(IsSender ? new Message(true) : new Message(false));
                }
            }
        }
    }

 

The UI

The MainWindow will be the start point for the application and will contains two user controls: ReceiverView and SenderView that will be showed if the user want to be a “Sender” or a “Receiver”.

The ReceiverView.xaml

The implementation will be something like

<UserControl x:Class="BluetoothSample.Views.ReceiverView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             DataContext="{Binding ReceiverViewModel, Source={StaticResource Locator}}"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="400">
    <StackPanel Margin="20"  Orientation="Vertical">
        <TextBlock>I am the Receiver</TextBlock>
        <StackPanel Orientation="Horizontal">
            <Button Margin="0,10,0,0" Width="80"  Command="{Binding StartCommand}" IsEnabled="{Binding IsStarEnabled}" Content="Start"/>
            <Button Margin="20,10,0,0" Width="80" Command="{Binding StopCommand}" IsEnabled="{Binding IsStopEnabled}" Content="Stop"/>
        </StackPanel>
        <TextBlock Margin="00,20,0,0" Text="Data:"/>
        <TextBlock Margin="00,20,0,0" Text="{Binding Data}"/>
    </StackPanel>
</UserControl>

The SenderView.xaml

The implementation will be something like

 

<UserControl x:Class="BluetoothSample.Views.SenderView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             DataContext="{Binding SenderViewModel,
                                   Source={StaticResource Locator}}"
             d:DesignHeight="400"
             d:DesignWidth="400"
             mc:Ignorable="d">
    <StackPanel Margin="20" Orientation="Vertical">
        <TextBlock>I am the Sender.</TextBlock>
        <TextBlock Margin="0,20,0,0">Select one device:</TextBlock>
        <ListBox Width="200"
                 Height="100"
                 MaxWidth="200"
                 MaxHeight="100"
                 Margin="0,20,0,0"
                 HorizontalAlignment="Left"
                 ItemsSource="{Binding Devices}"
                 SelectedItem="{Binding SelectDevice}" />
        <TextBlock Margin="0,20,0,0" Text="Write the data to send:" />
        <TextBox Margin="0,20,20,0" Text="{Binding Data, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <Button Width="80"
                Margin="0,20,20,0"
                HorizontalAlignment="Right"
                Command="{Binding SendCommand}"
                Content="Send" />
        <TextBlock Margin="0,20,0,0" TextWrapping="Wrap">
            Result:<Run Text="{Binding ResultValue}" />
        </TextBlock>
    </StackPanel>
</UserControl>

The MainWindow.xaml

The MainWindow will show/hide the user controls defined. The implementation is defined by

<Window x:Class="BluetoothSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:views="clr-namespace:BluetoothSample.Views"
        DataContext="{Binding Main, Source={StaticResource Locator}}"
        Title="Bluetooth Sample" 
        MinWidth="600" MinHeight="560"
        MaxWidth="600" MaxHeight="560">
    <StackPanel Orientation="Vertical">
        <GroupBox Margin="10,10,10,0"  Header="Choose the type:">
            <StackPanel Orientation="Horizontal">
                <RadioButton Margin="20" IsChecked="{Binding IsReceiver, Mode=TwoWay}">Receiver - will receive data from Sender</RadioButton>
                <RadioButton Margin="20" IsChecked="{Binding IsSender, Mode=TwoWay}">Sender - will send data for the Receiver</RadioButton>
            </StackPanel>
        </GroupBox>
        <GroupBox Margin="10,10,10,0" Header="Dashboard">
            <StackPanel Orientation="Vertical">
                <!-- visibility binding not worked in user control and 
                for this reason was added the stackpanel for each usercontrol-->
                <StackPanel Visibility="{Binding ReceiverVisibility}">
                    <views:ReceiverView Height="390" x:Name="ReceiverView"/>
                </StackPanel>
                <StackPanel Visibility="{Binding SenderVisibility}">
                    <views:SenderView Height="390"  x:Name="SenderView" />
                </StackPanel>
            </StackPanel>
        </GroupBox>
    </StackPanel>
</Window>

Note: For have a nice look, we will add the Modern UI nugget package. For see more about it, please read the following article

Modern UI for WPF application by example (Blank Window)

 

The ViewModelLocator

The ViewModelLocator will be a static resource for the application and is defined in App.xaml, as following

 

   <vm:ViewModelLocator xmlns:vm="clr-namespace:BluetoothSample.ViewModel"
                                 x:Key="Locator"
                                 d:IsDataSource="True" />

This class is where the setup for the view model and service are made and the implementation is something like

 public class ViewModelLocator
    {
        /// <summary>
        /// Initializes a new instance of the ViewModelLocator class.
        /// </summary>
        public ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

            SimpleIoc.Default.Register<IReceiverBluetoothService, ReceiverBluetoothService>();
            SimpleIoc.Default.Register<ISenderBluetoothService, SenderBluetoothService>();
            SimpleIoc.Default.Register<MainViewModel>();
            SimpleIoc.Default.Register<ReceiverViewModel>();
            SimpleIoc.Default.Register<SenderViewModel>();
        }

        /// <summary>
        /// Gets the main.
        /// </summary>
        /// <value>The main.</value>
        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }

        /// <summary>
        /// Gets the Receiver view model.
        /// </summary>
        /// <value>The Receiver view model.</value>
        public ReceiverViewModel ReceiverViewModel
        {
            get
            {
                return ServiceLocator.Current.GetInstance<ReceiverViewModel>();
            }
        }

        /// <summary>
        /// Gets the Sender view model.
        /// </summary>
        /// <value>The Sender view model.</value>
        public SenderViewModel SenderViewModel
        {
            get
            {
                return ServiceLocator.Current.GetInstance<SenderViewModel>();
            }
        }

        /// <summary>
        /// Cleanups this instance.
        /// </summary>
        public static void Cleanup()
        {
            // TODO Clear the ViewModels
        }
    }

 

Running the application

For test the application we need two devices, where in the first device we will run as “Sender” and in the second device we will run as “Receiver”.

The “Receiver” can start listening

The “Sender” is searching for available devices

The “Receiver” is starting for listening

 

The “Sender” can select a device for send the message

 

The “Sender” will send a message for the selected device

 

The “Receiver” received data sent by “Sender”

Conclusion

In conclusion, we can conclude the 32feet.Net is a great library for get all devices around with bluetooth on and for send data through bluetooth. The library has a great documentation but could have more samples that we could run for test the features provided.

Another point that the developer should be aware is the fact the project isn´t updated since 2012 but everyone can use the source code if needed, for fix any issue.

Source Code

The complete source code can be found in

Bluetooth Sample using 32feet.Net

Credits

Thanks to Pedro Lamas and Peter Foot  for help in make it work!

See More

Modern UI for WPF application by example (Default Window without back button)

Scope

This article has the goal to show how to create a default window in WPF using Modern UI, but without the back button.

Introduction

Modern UI is a set of controls and styles converting our WPF application into a great looking Modern UI app. The Modern UI project can be find in mui.codeplex.com, here is possible to get the WPF app that demostrate the features provided by “mui”.

Description

In the sample Modern UI for WPF application by example (Default Window) we saw the default window provided by Modern UI which contains a back button. Now we will change the ModernWindow style for remove the back button.

For start, we need to create, in our WPF application, a themes folder where we will add the resource dictionary, got from the original project, which contain the original style for ModernWindow.
source code

After it, we need to search in the style for back button, as following
back button

We can delete the button or only comment the code, and we need to define the key for the style. Here is the complete style

 <Style TargetType="mui:ModernWindow" x:Key="MyModernWindow">
        <Setter Property="BackgroundContent" Value="{DynamicResource WindowBackgroundContent}" />
        <Setter Property="FontFamily" Value="{DynamicResource DefaultFontFamily}" />
        <Setter Property="FontSize" Value="{DynamicResource DefaultFontSize}" />
        <Setter Property="Foreground" Value="{DynamicResource WindowText}" />
        <Setter Property="BorderBrush" Value="{DynamicResource WindowBorder}" />
        <Setter Property="Width" Value="800" />
        <Setter Property="Height" Value="640" />
        <Setter Property="MinWidth" Value="320" />
        <Setter Property="MinHeight" Value="320" />
        <Setter Property="ResizeMode" Value="CanResizeWithGrip" />
        <Setter Property="UseLayoutRounding" Value="True" />
        <Setter Property="TextOptions.TextFormattingMode" Value="Display" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="mui:ModernWindow">
                    <Border x:Name="WindowBorder" Margin="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}}">
                        <Border.Background>
                            <SolidColorBrush x:Name="WindowBorderBackground" Color="{DynamicResource WindowBackgroundColor}" />
                        </Border.Background>
                        <Border.Resources>
                            <Storyboard x:Key="BackgroundAnimation">
                                <ColorAnimation Storyboard.TargetName="WindowBorderBackground" Storyboard.TargetProperty="Color" To="{DynamicResource WindowBackgroundColor}" Duration="0:0:.6" />
                            </Storyboard>
                        </Border.Resources>

                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1">
                            <AdornerDecorator>
                                <Grid x:Name="LayoutRoot">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="36" />
                                        <RowDefinition Height="Auto" />
                                        <RowDefinition Height="*" />
                                    </Grid.RowDefinitions>

                                    <!-- window background content -->
                                    <ContentControl Grid.RowSpan="5" Content="{TemplateBinding BackgroundContent}" />

                                    <!-- title bar -->
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*" />
                                            <ColumnDefinition Width="Auto" />
                                            <ColumnDefinition Width="Auto" />
                                            <ColumnDefinition Width="96" />
                                        </Grid.ColumnDefinitions>

                                        <!-- title -->
                                        <TextBlock Text="{TemplateBinding Title}" Margin="8,0" VerticalAlignment="Center" Style="{StaticResource ModernWindowTitle}"
                                                   DataContext="{TemplateBinding IsTitleVisible}"
                                                   Visibility="{Binding Converter={StaticResource BooleanToVisibilityConverter}}"/>

                                        <!-- title links -->
                                        <ItemsControl Grid.Column="1" ItemsSource="{TemplateBinding TitleLinks}" Margin="0,0,24,0" WindowChrome.IsHitTestVisibleInChrome="True">
                                            <ItemsControl.ItemsPanel>
                                                <ItemsPanelTemplate>
                                                    <StackPanel Orientation="Horizontal" />
                                                </ItemsPanelTemplate>
                                            </ItemsControl.ItemsPanel>
                                            <ItemsControl.ItemTemplate>
                                                <DataTemplate>
                                                    <StackPanel Orientation="Horizontal">
                                                        <Line x:Name="Separator" X1=".5" Y1="3" X2=".5" Y2="12" Margin="5,0" VerticalAlignment="Center" Stroke="{DynamicResource SeparatorBackground}" />

                                                        <Button Content="{Binding DisplayName}"
                                                                Command="mui:LinkCommands.NavigateLink"
                                                                CommandParameter="{Binding Source}"
                                                                CommandTarget="{Binding ElementName=ContentFrame}"
                                                                Style="{StaticResource SystemButtonLink}" />
                                                    </StackPanel>
                                                    <DataTemplate.Triggers>
                                                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
                                                            <Setter Property="Visibility" TargetName="Separator" Value="Collapsed"/>
                                                        </DataTrigger>
                                                    </DataTemplate.Triggers>
                                                </DataTemplate>
                                            </ItemsControl.ItemTemplate>
                                        </ItemsControl>

                                        <!-- logo (visible only when LogoData is not null) -->
                                        <Border Grid.Column="2" Background="{DynamicResource Accent}" Width="36" Height="36" Margin="8,0"
                                                DataContext="{TemplateBinding LogoData}"
                                                Visibility="{Binding Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=inverse}">
                                            <Path Data="{Binding}" Stretch="Fill" Fill="White" Width="24" Height="24" HorizontalAlignment="Center" VerticalAlignment="Center" />
                                        </Border>

                                        <!-- window system buttons-->
                                        <StackPanel Grid.Column="3" Orientation="Horizontal" VerticalAlignment="Top" WindowChrome.IsHitTestVisibleInChrome="True">
                                            <Button Command="{Binding Source={x:Static SystemCommands.MinimizeWindowCommand}}" ToolTip="{x:Static modernUi:Resources.Minimize}" Style="{StaticResource SystemButton}">
                                                <Button.Content>
                                                    <Grid Width="13" Height="12" RenderTransform="1,0,0,1,0,1">
                                                        <Path Data="M0,6 L8,6 Z" Width="8" Height="7" VerticalAlignment="Center" HorizontalAlignment="Center"
                                                              Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="2"  />
                                                    </Grid>
                                                </Button.Content>
                                            </Button>
                                            <Grid Margin="1,0,1,0">
                                                <Button x:Name="Restore" Command="{Binding Source={x:Static SystemCommands.RestoreWindowCommand}}" ToolTip="{x:Static modernUi:Resources.Restore}" Style="{StaticResource SystemButton}" Visibility="Collapsed" >
                                                    <Button.Content>
                                                        <Grid Width="13" Height="12" UseLayoutRounding="True" RenderTransform="1,0,0,1,.5,.5">
                                                            <Path Data="M2,0 L8,0 L8,6 M0,3 L6,3 M0,2 L6,2 L6,8 L0,8 Z" Width="8" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center"
                                                                  Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="1"  />
                                                        </Grid>
                                                    </Button.Content>
                                                </Button>
                                                <Button x:Name="Maximize" Command="{Binding Source={x:Static SystemCommands.MaximizeWindowCommand}}" ToolTip="{x:Static modernUi:Resources.Maximize}" Style="{StaticResource SystemButton}" >
                                                    <Button.Content>
                                                        <Grid Width="13" Height="12">
                                                            <Path Data="M0,1 L9,1 L9,8 L0,8 Z" Width="9" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center"
                                                                  Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="2"  />
                                                        </Grid>
                                                    </Button.Content>
                                                </Button>
                                            </Grid>
                                            <Button Command="{Binding Source={x:Static SystemCommands.CloseWindowCommand}}" ToolTip="{x:Static modernUi:Resources.Close}" Style="{StaticResource SystemCloseButton}" >
                                                <Button.Content>
                                                    <Grid Width="13" Height="12" RenderTransform="1,0,0,1,0,1">
                                                        <Path Data="M0,0 L8,7 M8,0 L0,7 Z" Width="8" Height="7" VerticalAlignment="Center" HorizontalAlignment="Center"
                                                              Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="1.5"  />
                                                    </Grid>
                                                </Button.Content>
                                            </Button>
                                        </StackPanel>
                                    </Grid>

                                    <Grid Grid.Row="1">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="42" />
                                            <ColumnDefinition Width="*"/>
                                        </Grid.ColumnDefinitions>

                                        <!-- back button -->
                                        <!--<mui:ModernButton Margin="8,10,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"
                                                               EllipseDiameter="24" IconWidth="12" IconHeight="12" 
                                                               IconData="F1 M 33,22L 33,26L 19.75,26L 27,33L 20.5,33L 11,24L 20.5,15L 27,15L 19.75,22L 33,22 Z"
                                                               Command="NavigationCommands.BrowseBack"
                                                               CommandTarget="{Binding ElementName=ContentFrame}" 
                                                               ToolTip="{x:Static modernUi:Resources.Back}"
                                                               WindowChrome.IsHitTestVisibleInChrome="True" />-->

                                        <!-- main menu -->
                                        <mui:ModernMenu Grid.Column="1"
                                                             SelectedSource="{Binding Source, ElementName=ContentFrame, Mode=TwoWay}"
                                                             LinkGroups="{TemplateBinding MenuLinkGroups}" />
                                    </Grid>

                                    <!-- content frame -->
                                    <mui:ModernFrame x:Name="ContentFrame" Grid.Row="3" Grid.RowSpan="2" Margin="42,8,16,16" Source="{Binding ContentSource, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" ContentLoader="{TemplateBinding ContentLoader}"/>

                                    <!-- resize grip -->
                                    <Grid Grid.Row="2" x:Name="ResizeGrip" Background="Transparent" Visibility="Collapsed" HorizontalAlignment="Right" VerticalAlignment="Bottom" WindowChrome.ResizeGripDirection="BottomRight">
                                        <Path Width="12" Height="12" Margin="1" 
                                              Stroke="{DynamicResource WindowText}"
                                              StrokeThickness="1"
                                              Stretch="None"
                                              Data="F1 M1,10 L3,10 M5,10 L7,10 M9,10 L11,10 M2,9 L2,11 M6,9 L6,11 M10,9 L10,11 M5,6 L7,6 M9,6 L11,6 M6,5 L6,7 M10,5 L10,7 M9,2 L11,2 M10,1 L10,3" />
                                    </Grid>
                                </Grid>
                            </AdornerDecorator>
                        </Border>
                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsActive" Value="True">
                            <Setter Property="BorderBrush" Value="{DynamicResource WindowBorderActive}" />
                        </Trigger>
                        <Trigger Property="WindowState" Value="Maximized">
                            <Setter TargetName="Maximize" Property="Visibility" Value="Collapsed" />
                            <Setter TargetName="Restore" Property="Visibility" Value="Visible" />
                            <Setter TargetName="LayoutRoot" Property="Margin" Value="7" />
                        </Trigger>
                        <Trigger Property="WindowState" Value="Normal">
                            <Setter TargetName="Maximize" Property="Visibility" Value="Visible" />
                            <Setter TargetName="Restore" Property="Visibility" Value="Collapsed" />
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="ResizeMode" Value="CanResizeWithGrip" />
                                <Condition Property="WindowState" Value="Normal" />
                            </MultiTrigger.Conditions>
                            <Setter TargetName="ResizeGrip" Property="Visibility" Value="Visible" />
                        </MultiTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

 

After it, we need to define this style in the MainWindow, like as following

 

<mui:ModernWindow x:Class="ModernUIForWPFSample.WithoutBackButton.MainWindow"
                  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                  xmlns:mui="http://firstfloorsoftware.com/ModernUI"
                  Title="Modern UI without back button"
                  Width="650"
                  Height="550"
                  IsTitleVisible="True"
                  Style="{StaticResource MyModernWindow}">
....

 

In App.xaml.cs is required to add the following resources

<Application x:Class="ModernUIForWPFSample.WithoutBackButton.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.xaml" />
                <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.Light.xaml" />
                <ResourceDictionary Source="Themes/ModernWindow.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Here, in App.xaml, the difference from Default Windows sample is that we added the new resource dictionary  that contains the style we defined.

 

When we run the application we got something like

mui window

Note: the above image has all steps required.
For define the theme color for the Window, we need to define in the constructor the color, by doing

AppearanceManager.Current.AccentColor = Colors.DarkViolet;

For select the firt view that will show we need to do something like

 ContentSource = MenuLinkGroups.First().Links.First().Source;

 

Source code

Get the source code for this sample in github.

 

Visual Studio extension used

resharper    ghostdoc      stylecop