Device family state trigger pro UWP

WinUI XAML

7 years ago

Univerzální platforma Windows funguje na mnoha různých typech zařízení (device family). Aby aplikace vypadala skvěle na různých zařízeních, většinou lze použít AdaptiveTrigger, který reaguje na různá rozlišení displeje. Pokud však potřebujeme cílit na konkrétní rodinu zařízení, je možné si pro tento účel vytvořit vlastní state trigger.

Rozpoznání rodiny zařízení

Nejprve musíme zjistit, do jaké rodiny zařízení patří. To můžeme udělat pomocí jednoduché řetězcové hodnoty ve vlastnosti

Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily

Tato hodnota začíná prefixem Windows. , po které následuje název rodiny zařízení. Abychom mohli pracovat v silně typovaném prostředí, vytvoříme si jednoduchý device family helper který využívá výčtový typ.

/// <summary>
/// Represents different Windows 10 device families
/// </summary>
public enum DeviceFamily
{
    Unidentified,
    Desktop,
    Mobile,
    Xbox,
    Holographic,         
    IoT,
    Team,
}

/// <summary>
/// Retrieves strongly-typed device family
/// </summary>
public static class DeviceFamilyHelper
{
    static DeviceFamilyHelper()
    {
        DeviceFamily = RecognizeDeviceFamily(Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily);
    }

    public static DeviceFamily DeviceFamily { get; }

    private static DeviceFamily RecognizeDeviceFamily(string deviceFamily)
    {
        switch (deviceFamily)
        {
            case "Windows.Mobile":
                return DeviceFamily.Mobile;
            case "Windows.Desktop":
                return DeviceFamily.Desktop;
            case "Windows.Xbox":
                return DeviceFamily.Xbox;
            case "Windows.Holographic":
                return DeviceFamily.Holographic;
            case "Windows.IoT":
                return DeviceFamily.IoT;
            case "Windows.Team":
                return DeviceFamily.Team;
            default:
                return DeviceFamily.Unidentified;
        }
    }
}

Tento helper přečte systémovou vlastnost a rozpozná rodinu zařízení a uloží ji do read-only vlastnosti. Zahrnuli jsme i variantu Unidentified pro rodiny zařízení, které budou vydány až v budoucnu. Když se objeví nově podporovaný typ, můžeme přidat novou hodnotu do našeho výčtového typu a kód odpovídajícím způsobem aktualizovat.

Device family state trigger

Vytvoření vlastního state triggeru je poměrně jednoduché, zděděním od třídy StateTriggerBase a můžeme při tom využít náš nový helper:

/// <summary>
/// Trigger to differentiate between device families
/// </summary>
public class DeviceFamilyStateTrigger : StateTriggerBase
{
    public static readonly DependencyProperty TargetDeviceFamilyProperty = DependencyProperty.Register(
        "TargetDeviceFamily", typeof(DeviceFamily), typeof(DeviceFamilyStateTrigger), new PropertyMetadata(default(DeviceFamily), OnDeviceTypePropertyChanged));

    public DeviceFamily TargetDeviceFamily
    {
        get { return (DeviceFamily)GetValue(TargetDeviceFamilyProperty); }
        set { SetValue(TargetDeviceFamilyProperty, value); }
    }

    private static void OnDeviceTypePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
    {
        var trigger = (DeviceFamilyStateTrigger)dependencyObject;
        var newTargetDeviceFamily = (DeviceFamily)eventArgs.NewValue;
        trigger.SetActive(newTargetDeviceFamily == DeviceFamilyHelper.DeviceFamily);
    }         
}

Rodinu zařízení můžeme specifikovat pomocí vlastnosti TargetDeviceFamily a v reakci na událost PropertyChanged aktivovat nebo deaktivovat trigger.

<Grid>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState>
                <VisualState.StateTriggers>
                    <local:DeviceFamilyStateTrigger TargetDeviceFamily="Desktop" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="DesktopText.Visibility" Value="Visible" />
                </VisualState.Setters>
            </VisualState>
            <VisualState>
                <VisualState.StateTriggers>
                    <local:DeviceFamilyStateTrigger TargetDeviceFamily="Mobile" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="MobileText.Visibility" Value="Visible" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <TextBlock x:Name="DesktopText" Text="Desktop" Visibility="Collapsed" />
    <TextBlock x:Name="MobileText" Text="Mobile" Visibility="Collapsed" />
</Grid>

Tento jendoduchý úryvek kódu používá náš trigger a zobrazuje TextBlock, který odpovídá našemu zařízení. Náš trigger nyní můžeme použít pro zobrazení a skrývání ovladacích prvků, změnu ItemTemplate v seznamech a další úpravy.

Zdrojový kód

Zdrojový kód pro tento článek je dostupný na mém GitHubu.

Shrnutí

Pokud nabízíme uživatelům funkčnost specifickou pro konkrétní rodinu zařízení, je pravděpodobné, že budeme chtít upravit obsah zobrazený na stránce. V tom nám pomůže state trigger, který jsme si právě vytvořili. Pokud chcete dělat ještě drastičtější změny, můžete vytvořit separátní device family view. Tuto techniku si ukážeme v některém z příštích článků.