WPFxUPnP 2 その4

最後に、WPFでの画面です。

バイスのListを作成して、

public class UPnPLightList : ObservableCollection<UPnPLightDevice>
{
}

バイスのリストを、依存プロパティとして出して、バインドできるようにしています。
あとは、それぞれ、イベントハンドラを設定して、操作できるようにしています。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }
 
    // デバイス検索オブジェクト
    DeviceFinder deviceFinder = new DeviceFinder();
 
    // ロードイベントハンドラ
    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        deviceFinder.AddEvent += (addDevive) =>
            {
                // デバイス追加
                try
                {
                    LightList.Add(new UPnPLightDevice(addDevive));
                }
                catch (Exception) { }
            };
 
        deviceFinder.RemoveEvent += (removeDeviceUDN) =>
            {
                // デバイス削除
                try
                {
                    foreach (UPnPLightDevice one in LightList)
                    {
                        if (one.Device.UniqueDeviceName == removeDeviceUDN)
                        {
                            LightList.Remove(one);
 
                            Marshal.ReleaseComObject(one.Device);
                            break;
                        }
                    }
                }
                catch (Exception) { }
            };
 
        // デバイス検索開始
        deviceFinder.FindDeviceAsync("urn:schemas-upnp-org:device:DimmableLight:1");
    }
 
    // ライトデバイスリスト
    public static readonly DependencyProperty LightListProperty = DependencyProperty.Register("LightList",
                                                                      typeof(UPnPLightList),
                                                                      typeof(MainWindow),
                                                                      new PropertyMetadata(new UPnPLightList()));
    // ライトデバイスリスト
    public UPnPLightList LightList
    {
        get { return (UPnPLightList)this.GetValue(LightListProperty); }
        set { this.SetValue(LightListProperty, value); }
    }
 
    // Closeイベントハンドラ
    private void OnClosed(object sender, EventArgs e)
    {
        deviceFinder.CancelFindDeviceAsync();
    }
 
    // ONボタンクリックイベントハンドラ
    private void LightOn_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            UPnPLightDevice dev = (UPnPLightDevice)(DeviceList.SelectedItem);
            dev.SetTarget(true);
        }
        catch (Exception) { }
    }
 
    // OFFボタンクリックイベントハンドラ
    private void LightOff_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            UPnPLightDevice dev = (UPnPLightDevice)(DeviceList.SelectedItem);
            dev.SetTarget(false);
        }
        catch (Exception) { }
    }
 
    // 状態取得ボタンクリックイベントハンドラ
    private void LightStatus_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            UPnPLightDevice dev = (UPnPLightDevice)(DeviceList.SelectedItem);
            ResultStatus.Text = (dev.GetStatus() ? "ON" : "OFF");
        }
        catch (Exception) { }
    }
}

OnLoadedで、UPnPバイスの検索をかけて、追加・削除に応じて、作成したデバイスリストを生成して、追加します。
すると、デバイスが見つかった場合、インスタンスを作成し、リストに登録。
WPFフレームワークにより、リストに登録され表示されるようになります。
後は、イベントハンドラで、対象のインスタンスを操作して、UPnPバイスを操作します。

XAMLは、こんな感じ。

<Window x:Class="UPnPLightController.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="UPnP Light Controller" Height="250" Width="200" x:Name="Main"
        ResizeMode="NoResize" Loaded="OnLoaded" Closed="OnClosed">
    <StackPanel>
        <ComboBox x:Name="DeviceList" IsReadOnly="True"
                  ItemsSource="{Binding Path=LightList,ElementName=Main}"
                  DisplayMemberPath="Device.FriendlyName"/>
        <StackPanel Orientation="Horizontal">
            <Button x:Name="LightOn" Width="50" Content="ON" Click="LightOn_Click" />
            <Button x:Name="LightOff" Width="50" Content="OFF" Click="LightOff_Click" />
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Button x:Name="GetStatus" Width="50" Content="NOW" Click="LightStatus_Click" />
            <TextBlock x:Name="ResultStatus" Width="50" />
        </StackPanel>
        <Ellipse Height="100" Width="100" Margin="15"
                 IsEnabled="{Binding Path=SelectedItem.Status, ElementName=DeviceList}">
            <Ellipse.Style>
                <Style TargetType="{x:Type Ellipse}">
                    <Setter Property="Fill" Value="LightGray" />
                    <Style.Triggers>
                        <Trigger Property="IsEnabled" Value="True">
                            <Setter Property="Fill" Value="Yellow"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Ellipse.Style>
        </Ellipse>
    </StackPanel>
</Window>

これで、完成。