LampArray.AvailabilityChanged 事件

定义

IsAvailable 的值更改时引发;当用户通过设备设置更改对设备的系统访问权限时,可能会发生这种情况。

事件处理程序的参数是属性已更改的发送方 LampArray ,以及始终为 null) 的 Object (。

// Register
event_token AvailabilityChanged(TypedEventHandler<LampArray, IInspectable const&> const& handler) const;

// Revoke with event_token
void AvailabilityChanged(event_token const* cookie) const;

// Revoke with event_revoker
LampArray::AvailabilityChanged_revoker AvailabilityChanged(auto_revoke_t, TypedEventHandler<LampArray, IInspectable const&> const& handler) const;
/// [Windows.Foundation.Metadata.Experimental]
/// [add: Windows.Foundation.Metadata.Experimental]
/// [remove: Windows.Foundation.Metadata.Experimental]
// Register
event_token AvailabilityChanged(TypedEventHandler<LampArray, IInspectable const&> const& handler) const;

// Revoke with event_token
void AvailabilityChanged(event_token const* cookie) const;

// Revoke with event_revoker
LampArray::AvailabilityChanged_revoker AvailabilityChanged(auto_revoke_t, TypedEventHandler<LampArray, IInspectable const&> const& handler) const;
public event TypedEventHandler<LampArray,object> AvailabilityChanged;
[Windows.Foundation.Metadata.Experimental]
[add: Windows.Foundation.Metadata.Experimental]
[remove: Windows.Foundation.Metadata.Experimental]
public event TypedEventHandler<LampArray,object> AvailabilityChanged;
function onAvailabilityChanged(eventArgs) { /* Your code */ }
lampArray.addEventListener("availabilitychanged", onAvailabilityChanged);
lampArray.removeEventListener("availabilitychanged", onAvailabilityChanged);
- or -
lampArray.onavailabilitychanged = onAvailabilityChanged;
Public Custom Event AvailabilityChanged As TypedEventHandler(Of LampArray, Object) 

事件类型

属性

Windows 要求

设备系列
Windows 11 Insider Preview (在 10.0.23504.0 中引入)
API contract
Windows.Foundation.UniversalApiContract (在 v15.0 中引入)

示例

LampArray 示例

演示如何使用 Windows.Devices.Lights 和 Windows.Devices.Lights.Effects API 控制外围设备的 RGB 照明。

AutoRGB 示例

演示如何从桌面屏幕中提取具有代表性的单一颜色,并使用它来照亮连接的 RGB 设备上的 LED 灯。

AvailabilityChanged 事件示例

以下示例演示如何为 AvailabilityChanged 事件设置处理程序。 请注意,代码在声明处理程序之前如何首先检查 属性是否 IsAvailable 可用。

using System;
using System.Collections.Generic;
using Windows.Devices.Enumeration;
using Windows.Devices.Lights;

namespace Sample
{
    class LampArrayHelper
    {
        private readonly DeviceWatcher watcher;
        private readonly Dictionary<string, LampArray> lampArrays;
        private readonly Dictionary<string, LampArrayEffectPlaylist> playlists;

        public LampArraySample()
        {
            lampArrays = new Dictionary<string, LampArray>();
            playlists = new Dictionary<string, LampArrayEffectPlaylist>();

            watcher = DeviceInformation.CreateWatcher(LampArray.GetDeviceSelector());

            watcher.Added += Watcher_Added;
            watcher.Removed += Watcher_Removed;

            watcher.Start();
        }

        private void DoEffectSetup(LampArray device)
        {
            Console.WriteLine("Starting effect playlist...");

            var indices = Enumerable.Range(0, device.LampCount).ToArray();

            var effect = new LampArraySolidEffect(device, indices)
            {
                Color = Colors.Red,
                CompletionBehavior = LampArrayEffectCompletionBehavior.KeepState,
                Duration = TimeSpan.FromMilliseconds(3000)
            };

            var effect2 = new LampArraySolidEffect(device, indices)
            {
                Color = Colors.Blue,
                CompletionBehavior = LampArrayEffectCompletionBehavior.KeepState,
                Duration = TimeSpan.FromMilliseconds(3000)
            };

            var playlist = new LampArrayEffectPlaylist();
            playlist.Append(effect);
            playlist.Append(effect2);
            playlist.Start();

            lock (playlists)
            {
                playlists.Add(device.DeviceId, playlist);
            }
        }

        private async void Watcher_Added(DeviceWatcher sender, DeviceInformation args)
        {
            var lampArray = await LampArray.FromIdAsync(args.Id);

            lock (lampArrays)
            {
                lampArrays[args.Id] = lampArray;
            }

            if (lampArray.LampArrayKind == LampArrayKind.Headset)
            {
                Console.WriteLine("Headset LampArray attached: " + lampArray.DeviceId);
            }

            if (ApiInformation.IsPropertyPresent("Windows.Devices.Lights.LampArray", "IsAvailable"))
            {
                if (lampArray.IsAvailable)
                {
                    DoEffectSetup(lampArray);
                }

                lampArray.AvailabilityChanged += LampArray_AvailabilityChanged;
            }
            else
            {
                DoEffectSetup(lampArray);
            }
        }

        private void Watcher_Removed(DeviceWatcher sender, DeviceInformationUpdate args)
        {
            lock (lampArrays)
            {
                lampArrays.Remove(args.Id);
            }

            lock (playlists)
            {
                if (playlists.ContainsKey(args.Id))
                {
                    playlists[args.Id].Stop();
                    playlists.Remove(args.Id);
                }
            }
        }

        private void LampArray_AvailabilityChanged(LampArray sender, object args)
        {
            if (sender.IsAvailable)
            {
                Console.WriteLine("Device available: " + sender.DeviceId);
                DoEffectSetup(sender);
            }
            else
            {
                Console.WriteLine("Device unavailable: " + sender.DeviceId);

                lock (playlists)
                {
                    if (playlists.ContainsKey(sender.DeviceId))
                    {
                        playlists[sender.DeviceId].Stop();
                        playlists.Remove(sender.DeviceId);
                    }
                }
            }
        }
    }
}
#include <windows.h>

#include <algorithm>
#include <memory>
#include <numeric>
#include <vector>
#include <map>

#include <wil/resource.h>

#include <winrt/base.h>
#include <winrt/windows.devices.lights.h>
#include <winrt/windows.devices.lights.effects.h>
#include <winrt/windows.devices.enumeration.h>
#include <winrt/windows.foundation.h>
#include <winrt/windows.foundation.metadata.h>
#include <winrt/windows.ui.h>

namespace winrt
{
    using namespace winrt::Windows::Devices::Enumeration;
    using namespace winrt::Windows::Devices::Lights;
    using namespace winrt::Windows::Devices::Lights::Effects;
    using namespace winrt::Windows::Foundation;
    using namespace winrt::Windows::Foundation::Metadata;
    using namespace winrt::Windows::UI;
}

wil::srwlock lampArraysLock;
std::shared_ptr<std::map<winrt::hstring, winrt::LampArray>> lampArrays;

wil::srwlock playlistsLock;
std::shared_ptr<std::map<winrt::hstring, winrt::LampArrayEffectPlaylist>> playlists;

void DoEffectSetup(winrt::LampArray device)
{
    wprintf(L"Starting effect playlist...\n");

    std::vector<int32_t> indices(device.LampCount());
    std::iota(indices.begin(), indices.end(), 0);

    auto effect = winrt::LampArraySolidEffect(device, indices);
    effect.Color(winrt::Colors::Red());
    effect.CompletionBehavior(winrt::LampArrayEffectCompletionBehavior::KeepState);
    effect.Duration(std::chrono::milliseconds(3000));

    auto effect2 = winrt::LampArraySolidEffect(device, indices);
    effect2.Color(winrt::Colors::Blue());
    effect2.CompletionBehavior(winrt::LampArrayEffectCompletionBehavior::KeepState);
    effect2.Duration(std::chrono::milliseconds(3000));

    auto playlist = winrt::LampArrayEffectPlaylist();
    playlist.RepetitionMode(winrt::LampArrayRepetitionMode::Forever);

    playlist.Append(effect);
    playlist.Append(effect2);
    playlist.Start();

    auto lock = playlistsLock.lock_exclusive();
    playlists->emplace(std::make_pair(device.DeviceId(), playlist));
}

int __cdecl main()
{
    lampArrays = std::make_shared<std::map<winrt::hstring, winrt::LampArray>>();
    playlists = std::make_shared<std::map<winrt::hstring, winrt::LampArrayEffectPlaylist>>();

    auto deviceWatcher = winrt::DeviceInformation::CreateWatcher(winrt::LampArray::GetDeviceSelector());

    auto deviceAddedRevoker = deviceWatcher.Added(winrt::auto_revoke, [](winrt::DeviceWatcher, winrt::DeviceInformation info)
    {
        auto deviceId = info.Id();
        auto lampArray = winrt::LampArray::FromIdAsync(deviceId).get();

        if (lampArray)
        {
            wprintf(L"LampArray %s added\n", deviceId.c_str());

            {
                auto lock = lampArraysLock.lock_exclusive();
                lampArrays->emplace(std::make_pair(deviceId, lampArray));
            }

            if (winrt::ApiInformation::IsPropertyPresent(L"Windows.Devices.Lights.LampArray", L"IsAvailable"))
            {
                if (lampArray.IsAvailable())
                {
                    DoEffectSetup(lampArray);
                }

                lampArray.AvailabilityChanged([](winrt::LampArray device, winrt::IInspectable)
                {
                    if (device.IsAvailable())
                    {
                        wprintf(L"Device available: %s\n", device.DeviceId().c_str());
                        DoEffectSetup(device);
                    }
                    else
                    {
                        wprintf(L"Device unavailable: %s\n", device.DeviceId().c_str());

                        auto lock = playlistsLock.lock_exclusive();

                        auto entry = playlists->find(device.DeviceId());
                        if (entry != playlists->end())
                        {
                            entry->second.Stop();
                            playlists->erase(entry);
                        }
                    }
                });
            }
            else
            {
                DoEffectSetup(lampArray);
            }
        }
    });

    auto deviceRemovedRevoker = deviceWatcher.Removed(winrt::auto_revoke, [](winrt::DeviceWatcher, winrt::DeviceInformationUpdate info)
    {
        auto deviceId = info.Id();

        {
            auto lock = lampArraysLock.lock_exclusive();
            lampArrays->erase(deviceId);
        }

        {
            auto lock = playlistsLock.lock_exclusive();

            auto entry = playlists->find(deviceId);
            if (entry != playlists->end())
            {
                entry->second.Stop();
                playlists->erase(entry);
            }
        }

        wprintf(L"LampArray %s removed\n", deviceId.c_str());
    });

    deviceWatcher.Start();

    wprintf(L"Press any key to exit\n");
    getchar();

    deviceWatcher.Stop();

    return 0;
}

注解

前台和后台 (“环境”) 应用都可以接收和处理此事件。

若要使用此事件,必须在应用清单中声明“com.microsoft.windows.lighting”AppExtension。 有关如何执行此操作的详细信息,请参阅 创建和托管应用扩展

<Extensions>
    <uap3:Extension Category="windows.appExtension">
        <uap3:AppExtension Name="com.microsoft.windows.lighting" Id="Id" DisplayName="Id">
        </uap3:AppExtension> 
    </uap3:Extension>
</Extensions>

适用于

另请参阅