Sunday, 31 August 2014

List Devices

How to list all the devices that are connected, first lets create a DeviceItem class to store all of our device properties.

public class DeviceItem
{
    public string DeviceName { get; set; }
    public String DeviceId { get; set; }
    public BitmapImage DeviceThumb { get; set; }
    public BitmapImage DeviceGlyph { get; set; }

    public DeviceItem(DeviceInformation Di, DeviceThumbnail glyph, DeviceThumbnail thumb)
    {
        this.DeviceName = Di.Properties["System.ItemNameDisplay"].ToString();
        this.DeviceId = String.Format("Device ID: {0}", Di.Id);
        this.DeviceThumb = new BitmapImage();
        this.DeviceThumb.SetSource(thumb);
        this.DeviceGlyph = new BitmapImage();
        this.DeviceGlyph.SetSource(glyph);
    }
}

Easy enough, next lets create UI that we can use to display all of our devices.

<Page
    x:Class="pc.devicesExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:pc.devicesExample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ScrollViewer Margin="50">
            <ListView x:Name="MyListView" >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Image Height="100" Source="{Binding DeviceThumb}"/>
                            <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                                <Image Source="{Binding DeviceGlyph}"/>
                                <StackPanel Margin="10">
                                    <TextBlock Text="{Binding DeviceName}"/>
                                    <TextBlock Text="{Binding DeviceId}" />
                                </StackPanel>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </ScrollViewer>
    </Grid>
</Page>


now we created an ListView with an item template, so now we have to set our listviews itemssource property with a list of our DeviceItems, so let's jump to our code behind.

using System;
using System.Collections.Generic;
using System.Linq;
using Windows.Devices.Enumeration;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media.Imaging;

namespace pc.devicesExample
{
public class DeviceItem
{
    public string DeviceName { get; set; }
    public String DeviceId { get; set; }
    public BitmapImage DeviceThumb { get; set; }
    public BitmapImage DeviceGlyph { get; set; }

    public DeviceItem(DeviceInformation Di, DeviceThumbnail glyph, DeviceThumbnail thumb)
    {
        this.DeviceName = Di.Properties["System.ItemNameDisplay"].ToString();
        this.DeviceId = String.Format("Device ID: {0}", Di.Id);
        this.DeviceThumb = new BitmapImage();
        this.DeviceThumb.SetSource(thumb);
        this.DeviceGlyph = new BitmapImage();
        this.DeviceGlyph.SetSource(glyph);
    }
}

    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.Init();
        }

        async void Init()
        {
            var deviceList = new List<DeviceItem>();
            var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync();

            foreach (var di in devices.ToList())
            {
                var glyph = await di.GetGlyphThumbnailAsync();
                var thumb = await di.GetThumbnailAsync();

                deviceList.Add(new DeviceItem(di, glyph, thumb));
            }

            this.MyListView.ItemsSource = deviceList;
        }
    }
}

and this is what our finished product should look like

pretty sweet, but now lets add some filtering capabilities

so lets add a drop down above our scrollviewer to let us filter our devices, first lets append our UI
<Page
    x:Class="pc.devicesExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:pc.devicesExample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <!--Modification-->
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ComboBox x:Name="DeviceTypes_CB" Margin="50" Grid.Column="0" />
        <!--Modification-->
        <ScrollViewer Grid.Row="1" Margin="50">
            <ListView x:Name="MyListView" >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Image Height="100" Source="{Binding DeviceThumb}"/>
                            <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                                <Image Source="{Binding DeviceGlyph}"/>
                                <StackPanel Margin="10">
                                    <TextBlock Text="{Binding DeviceName}"/>
                                    <TextBlock Text="{Binding DeviceId}" />
                                </StackPanel>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </ScrollViewer>
    </Grid>
</Page>


we just changed our grid to have two rows and on the top one we added a combo box to hold all of our options, next let's change our codebehind.

using System;
using System.Collections.Generic;
using System.Linq;
using Windows.Devices.Enumeration;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media.Imaging;

namespace pc.devicesExample
{
public class DeviceItem
{
    public string DeviceName { get; set; }
    public String DeviceId { get; set; }
    public BitmapImage DeviceThumb { get; set; }
    public BitmapImage DeviceGlyph { get; set; }

    public DeviceItem(DeviceInformation Di, DeviceThumbnail glyph, DeviceThumbnail thumb)
    {      
        this.DeviceName = Di.Properties["System.ItemNameDisplay"].ToString();
        this.DeviceId = String.Format("Device ID: {0}", Di.Id);
        this.DeviceThumb = new BitmapImage();
        this.DeviceThumb.SetSource(thumb);
        this.DeviceGlyph = new BitmapImage();
        this.DeviceGlyph.SetSource(glyph);
    }
}

    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.Init();

            DeviceTypes_CB.ItemsSource = Enum.GetValues(typeof(DeviceClass));
            //added event reciever for combobox to to fire when the
            //selection chagnes
            DeviceTypes_CB.SelectionChanged += DeviceTypes_CB_SelectionChanged;
        }

        //eventhander to re fire the init method with the selected device type
        void DeviceTypes_CB_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this.Init((DeviceClass)e.AddedItems[0]);
        }

        //added default paramter to init class to get all devices if not specified
        async void Init(DeviceClass dc = DeviceClass.All)
        {
            var deviceList = new List<DeviceItem>();

            //get devices based on input paratmeter
            var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(dc);

            foreach (var di in devices.ToList())
            {
                var glyph = await di.GetGlyphThumbnailAsync();
                var thumb = await di.GetThumbnailAsync();

                deviceList.Add(new DeviceItem(di, glyph, thumb));
            }

            this.MyListView.ItemsSource = deviceList;
        }
    }
}

Some simple changes, basically we added an event handler to our combo box to set the item source of our listview when we change the type of devics we would like to list.