Category Archives: UWP

UWP Transparent title bar

In the last post I extended the view into the title bar on a UWP application, which looks great with the NavigationView or the likes.

However, if you then place a view, such as a SplitView, on the right of the screen the title bar buttons (minimize, maximize and close) will appear in a different colour (if using the default colours).

So we can make the button backgrounds transparent like this

var titleBar = ApplicationView.GetForCurrentView().TitleBar;
titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;

How to extend a UWP page into the titlebar

If you want your page/view to extend into the title bar area (in other words no longer having a title bar), then OnLaunched add the following

CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;

and add this using clause

using Windows.ApplicationModel.Core;

Enumerating available devices in UWP

In my previous post (Displaying the device picker in a UWP application) I showed how to reuse the UWP device picker flyout within an application.

However, it’s possible that the developer would prefer to offer devices in some alternate UI or, of course, simply locate a known device for an application to use. In the previous post I looked at filtering for Bluetooth devices and those are what I’m after for a little application I’m writing in which I do not require the DevicePicker UI.

Filtering

Before I get into code to enumerate the devices, I’ll first expand on the lines of code from my previous post, that look like this

BluetoothDevice.GetDeviceSelectorFromPairingState(false)

Each of the lines like this one actually returns a string which is an Advanced Query Syntax (AQS) language query. So for example this line will produce the following string (formatted to make it more readable)

System.Devices.DevObjectType:=5 AND 
System.Devices.Aep.ProtocolId:=\"{E0CBF06C-CD8B-4647-BB8A-263B43F0F974}\" AND 
(System.Devices.Aep.IsPaired:=System.StructuredQueryType.Boolean#False OR
System.Devices.Aep.Bluetooth.IssueInquiry:=System.StructuredQueryType.Boolean#True)

For completeness, here’s the results of each of the other GetDeviceSelectorFromPairingState calls

BluetoothLEDevice.GetDeviceSelectorFromPairingState(false)

System.Devices.DevObjectType:=5 AND 
System.Devices.Aep.ProtocolId:=\"{BB7BB05E-5972-42B5-94FC-76EAA7084D49}\" AND 
(System.Devices.Aep.IsPaired:=System.StructuredQueryType.Boolean#False OR 
System.Devices.Aep.Bluetooth.IssueInquiry:=System.StructuredQueryType.Boolean#True)

BluetoothLEDevice.GetDeviceSelectorFromPairingState(true)

System.Devices.DevObjectType:=5 AND 
System.Devices.Aep.ProtocolId:=\"{BB7BB05E-5972-42B5-94FC-76EAA7084D49}\" AND 
(System.Devices.Aep.IsPaired:=System.StructuredQueryType.Boolean#True OR 
System.Devices.Aep.Bluetooth.IssueInquiry:=System.StructuredQueryType.Boolean#False)

BluetoothDevice.GetDeviceSelectorFromPairingState(true)

System.Devices.DevObjectType:=5 AND 
System.Devices.Aep.ProtocolId:=\"{E0CBF06C-CD8B-4647-BB8A-263B43F0F974}\" AND 
(System.Devices.Aep.IsPaired:=System.StructuredQueryType.Boolean#True OR 
System.Devices.Aep.Bluetooth.IssueInquiry:=System.StructuredQueryType.Boolean#False)

Hence we could now create our own AQS query to search for devices.

See Using Advanced Query Syntax Programmatically for more information on AQS.

Enumerating over devices (simple approach)

A simple approach to enumerating over all the available devices is to use the DeviceInformation.FindAllAsync() method, which is async/await compatible, hence we simply use it like this

var devices = await DeviceInformation.FindAllAsync();

// output all devices
foreach (var device in devices)
{
   Debug.WriteLine(device.Name);
}

Obviously this is a little over the top if we’re looking for a specific device or set of devices. In such cases we can create an AQS query and pass this into one of the FindAllAsync overloads. Hence to recreate my previous post’s query looking for all Bluetooth devices we might prefer to use

var devices = await DeviceInformation.FindAllAsync(
    BluetoothDevice.GetDeviceSelectorFromPairingState(
        false));

Whilst this solution to the problem of locating devices may fulfil many of the developer’s requirements, an area it fails on is that once the developer has a list of devices they do not have a way to tell when devices are turned off/disabled/or otherwise no longer available. In such situations it’s better to watch for device changes.

Watching for device changes

The DeviceInformation.CreateWatcher method allows the developer to query for devices and via events, watch for items to be added, updated or removed. This would suit an RX type of implementation.

Here’s some code that demonstrates possible usage of the CreateWatcher

try
{
   deviceWatcher = DeviceInformation.CreateWatcher(
      BluetoothDevice.GetDeviceSelectorFromPairingState(false), 
      null,
      DeviceInformationKind.Device);

      deviceWatcher.Added += (watcher, args) =>
      {
         Debug.WriteLine($"Added {args.Name}");
      };
      deviceWatcher.Updated += (watcher, args) =>
      {
         Debug.WriteLine($"Updated {args.Id}");
      };
      deviceWatcher.Removed += (watcher, args) =>
      {
         Debug.WriteLine($"Removed {args.Id}");
      };
      deviceWatcher.EnumerationCompleted += (watcher, args) => 
      { 
         Debug.WriteLine("No more devices found"); 
      };
      deviceWatcher.Start();
}
catch (ArgumentException ex)
{
   Debug.WriteLine(ex.Message);
}

Again we’re using the AQS created via the GetDeviceSelectoryFromPairingState method and in this simplistic example, we simply subscribe to the Added/Updated/Removed and EnumerationCompleted events to output what devices have been added etc. We also need to be aware of possible ArgumentExceptions, such as incorrectly formatted GUID’s etc. See DeviceInformation Class for a more complete example of this usage.

Displaying the device picker in a UWP application

Developers can use the UWP device picker flyout control within their application to allow the user to select a device from a list of available devices. The list can be filtered to display only particular types of devices.

For example, here’s how to display the DevicePicker flyout without filtering, i.e. showing all available devices

var devicePicker = new DevicePicker();
devicePicker.Show(new Rect(x, y, width, height));

In this case we simply create a DevicePicker and call the Show method which is passed a rectangle where you want the picker to flyout from.

There’s an overload Show method which allows a placement as well.

If you run this code in your application you’ll find that devices are enumerated over and displayed as they are found, so obviously this may take a little bit of time to enumerate all devices.

In most cases we probably want to filter the DevicePicker for a certain type of device. For example if we want to locate all Bluetooth devices we would use the following

var devicePicker = new DevicePicker();

devicePicker.Filter
   .SupportedDeviceSelectors.Add(
      BluetoothLEDevice.GetDeviceSelectorFromPairingState(false));
devicePicker.Filter
   .SupportedDeviceSelectors.Add(
      BluetoothLEDevice.GetDeviceSelectorFromPairingState(true));
devicePicker.Filter
   .SupportedDeviceSelectors.Add(
      BluetoothDevice.GetDeviceSelectorFromPairingState(false));
devicePicker.Filter
   .SupportedDeviceSelectors.Add(
      BluetoothDevice.GetDeviceSelectorFromPairingState(true));

devicePicker.Show(new Rect(x, y, width, height));

In this case we’ve filtered the DevicePicker so it will only display BluetoothLE devices and Bluetooth devices both in a paired (the true parameter) or unpaired (the false parameter).

Obviously we’re going to want to get at the device information or the selected device, when using the Show method, we will need to subscribe to the DevicePicker’s DeviceSelected event, for example

devicePicker.DeviceSelected += (picker, args) =>
{
   // outputs the selected device name
   Debug.WriteLine(args.SelectedDevice.Name);
};

We can also respond to a couple of other events such as the DevicePickerDismissed and DisconnectButtonClicked.

As an alternate to the event approach, we could switch from using the Show method to use the async/await implementation which combines the Show and the DeviceSelected into he PickSingleDeviceAsync method, i.e.

var device = await 
   devicePicker.PickSingleDeviceAsync(
      new Rect(x, y, width, height));
// outputs the selected device name
Debug.WriteLine(device.Name);