Rugalmas elrendezés

Az XAML-elrendezési rendszer automatikusan méretezi az elemeket, az elrendezéspaneleket és a vizualizációs állapotokat, így rugalmas felhasználói felületet hozhat létre. A rugalmas elrendezéssel az alkalmazás nagyszerűen néz ki különböző alkalmazásablak-méretekkel, felbontásokkal, képpontsűrűséggel és tájolással rendelkező képernyőkön. Az XAML használatával áthelyezheti, átméretezheti, átcsordulhatja, megjelenítheti/elrejtheti, lecserélheti vagy újratervezheti az alkalmazás felhasználói felületét, ahogyan azt a rugalmas tervezési technikák is ismertetik. Itt bemutatjuk, hogyan implementálhat rugalmas elrendezéseket az XAML használatával.

Rugalmas elrendezések tulajdonságokkal és panelekkel

A rugalmas elrendezés alapja az XAML elrendezés tulajdonságainak és paneljeinek megfelelő használata a tartalom folyékony áthelyezéséhez, átméretezéséhez és átcsordulásához.

Az XAML elrendezési rendszer a statikus és a folyékony elrendezéseket is támogatja. Statikus elrendezésben explicit képpontméreteket és pozíciókat adhat a vezérlőknek. Amikor a felhasználó módosítja az eszköz felbontását vagy tájolását, a felhasználói felület nem változik. A statikus elrendezések elcsúszhatnak különböző formátumok és megjelenítési méretek esetén. Másrészt a folyadékelrendezések zsugorodnak, növekednek és újrafolynak, hogy reagáljanak az eszközön elérhető vizuális térre.

A gyakorlatban statikus és folyadékelemek kombinációjával hozza létre a felhasználói felületet. Bizonyos helyeken továbbra is statikus elemeket és értékeket használ, de győződjön meg arról, hogy a teljes felhasználói felület reagál a különböző felbontásokra, képernyőméretekre és nézetekre.

Itt bemutatjuk, hogyan használható az XAML-tulajdonságok és az elrendezéspanelek a folyadékelrendezés létrehozásához.

Elrendezés tulajdonságai

Az elrendezés tulajdonságai az elemek méretét és pozícióját szabályozzák. A folyékony elrendezés létrehozásához használjon automatikus vagy arányos méretezést az elemekhez, és engedélyezze az elrendezéspanelek számára, hogy szükség szerint helyezzék el gyermekeiket.

Az alábbiakban néhány gyakori elrendezési tulajdonságot talál, és megtudhatja, hogyan hozhat létre folyadékelrendezéseket.

Magasság és szélesség

A Magasság és a Szélesség tulajdonság határozza meg egy elem méretét. Használhatja az érvényes képpontokban mért rögzített értékeket, vagy használhat automatikus vagy arányos méretezést.

Az automatikus méretezés átméretezi a felhasználói felület elemeit a tartalomhoz vagy a szülőtárolóhoz való igazításhoz. Az automatikus méretezést a táblázat soraival és oszlopaival is használhatja. Az automatikus méretezés használatához állítsa a felhasználói felület elemeinek magasságát és/vagy szélességét Automatikus értékre.

Megjegyzés:

Az, hogy egy elem a tartalmához vagy a tárolójához igazodva átméreteződik, attól függ, hogyan kezeli a szülőtároló a gyermekek méretezését. További információ: Elrendezési panelek a cikk későbbi részében.

Az arányos méretezés( más néven csillagméretezés) a rács sorai és oszlopai között súlyozott arányok szerint osztja el a rendelkezésre álló területet. XAML-ben a csillagértékek *-ként (vagy n*-ként) vannak kifejezve a súlyozott csillagméretezéshez. Ha például meg szeretné adni, hogy egy oszlop 5-ször szélesebb a második oszlopnál egy kétoszlopos elrendezésben, használja az "5*" és a "*" értéket a ColumnDefinition elemek Szélesség tulajdonságaihoz.

Ez a példa egy rács rögzített, automatikus és arányos méretezését egyesíti 4 oszloppal.

oszlop Sizing Description
Oszlop_1 automatikus Az oszlop mérete a tartalmához igazodik.
Oszlop_2 * Az automatikus oszlopok kiszámítása után az oszlop a fennmaradó szélesség egy részét kapja meg. Column_2 fele olyan széles lesz, mint Column_4.
Oszlop_3 44 Az oszlop 44 képpont széles lesz.
Oszlop_4 2* Az automatikus oszlopok kiszámítása után az oszlop a fennmaradó szélesség egy részét kapja meg. Column_4 kétszer olyan széles lesz, mint Column_2.

Az alapértelmezett oszlopszélesség "*", ezért nem kell explicit módon beállítania ezt az értéket a második oszlophoz.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition/>
        <ColumnDefinition Width="44"/>
        <ColumnDefinition Width="2*"/>
    </Grid.ColumnDefinitions>
    <TextBlock Text="Column 1 sizes to its content." FontSize="24"/>
</Grid>

Ha futásidőben szeretné lekérni egy elem méretét, használja az írásvédett ActualHeight és ActualWidth tulajdonságokat a Magasság és Szélesség tulajdonságok helyett.

Méretkorlátozások

Ha automatikus méretezést használ a felhasználói felületen, előfordulhat, hogy kényszereket kell alkalmaznia egy elem méretére. Beállíthatja a MinWidth/ és MinHeight/MaxHeight tulajdonságokat olyan értékek megadásához, amelyek korlátozzák egy elem méretét, miközben lehetővé teszik a folyadék átméretezését.

A Rácsban a MinWidth/MaxWidth oszlopdefiníciókkal is használható, a MinHeight/MaxHeight pedig sordefiníciókkal.

Igazítás

A HorizontalAlignment és a VerticalAlignment tulajdonsággal megadhatja, hogyan kell elhelyezni egy elemet a szülőtárolóban.

  • A HorizontalAlignment értékei Bal, Közép, Jobb és Stretch.
  • A VerticalAlignment értéke a Felső, a Közép, az Alsó és a Stretch.

A Stretch igazítással az elemek kitöltik a szülőtárolóban biztosított összes területet. Mindkét igazítási tulajdonság esetében a Stretch az alapértelmezett érték. Egyes vezérlők, például a Button azonban felülírják ezt az értéket az alapértelmezett stílusukban. Minden olyan elem, amely rendelkezhet gyermekelemekkel, egyedileg kezelheti a HorizontalAlignment és a VerticalAlignment tulajdonságok Stretch értékét. Egy alapértelmezett Stretch értékeket használó elem például egy rácsban elhelyezve megnyúlik, hogy kitöltse azt a cellát, amely tartalmazza. Ugyanaz az elem, ha vászonon van elhelyezve, a tartalmához igazítja a méretét. További információ arról, hogy az egyes panelek hogyan kezelik a Stretch értéket, olvassa el az Elrendezés panelek című cikket.

További információért lásd az Igazítás, margó és kitöltés cikket, valamint a HorizontalAlignment és VerticalAlignment referenciaoldalakat.

Láthatóság

Az elemeket úgy jelenítheti meg vagy rejtheti el, hogy a Láthatóság tulajdonságát a láthatósági enumerálási értékek egyikére állítja: Látható vagy Összecsukva. Ha egy elem összecsukva van, az nem foglal helyet a felhasználói felület elrendezésében.

Az elemek láthatósági tulajdonságát kódban vagy vizualizációs állapotban is módosíthatja. Ha egy elem láthatósága megváltozik, az összes gyermekeleme is megváltozik. A felhasználói felület szakaszait lecserélheti úgy, hogy egy panelt jelenít meg, miközben összecsuk egy másikat.

Jótanács

Ha a felhasználói felületen alapértelmezés szerint összecsukott elemek vannak, az objektumok akkor is létrejönnek indításkor, ha azok nem láthatók. Az ilyen elemek betöltését elhalaszthatja, amíg azok szükségesek, az x:Load attribútum használatával késleltetve az objektumok létrehozását. Ez javíthatja az indítási teljesítményt. További információ : x:Load attribútum.

Stíluserőforrások

Nem kell külön-külön beállítania az egyes tulajdonságértékeket egy vezérlőelemen. Általában hatékonyabb a tulajdonságértékek csoportosítása stíluserőforrásba, és a stílus alkalmazása egy vezérlőelemre. Ez különösen akkor igaz, ha ugyanazokat a tulajdonságértékeket több vezérlőre is alkalmaznia kell. A stílusok használatáról további információt a Stílusvezérlők című témakörben talál.

Elrendezés panelek

A vizualizációs objektumok elhelyezéséhez egy panelen vagy más tárolóobjektumban kell elhelyeznie őket. Az XAML-keretrendszer különböző panelosztályokat biztosít, például Vászon, Rács, RelativePanel és StackPanel, amelyek tárolókként szolgálnak, és lehetővé teszik a felhasználói felület elemeinek elhelyezését és elrendezését.

Az elrendezési panel kiválasztásakor a legfontosabb szempont, hogy a panel hogyan pozinálja és méretezi a gyermekelemeket. Érdemes azt is figyelembe venni, hogyan vannak egymásra rétegezve az egymást átfedő gyermekelemek.

Íme az XAML-keretrendszerben található panelvezérlők fő jellemzőinek összehasonlítása.

Vezérlőpanel Description
Canvas Canvas nem támogatja a rugalmas felhasználói felületet; Ön szabályozza a gyermekelemek elhelyezésének és méretezésének összes aspektusát. Általában speciális esetekben, például grafikus elemek létrehozására vagy nagyobb adaptív felhasználói felület kis statikus területeinek meghatározására használja. Az elemek futásidőben való áthelyezéséhez kód- vagy vizualizációállapotokat használhat.
  • Az elemek teljesen Canvas.Top és Canvas.Left csatolt tulajdonságok használatával vannak elhelyezve.
  • A rétegzés explicit módon megadható a Canvas.ZIndex csatolt tulajdonságával.
  • A HorizontalAlignment/VerticalAlignment stretch értékei figyelmen kívül lesznek hagyva. Ha egy elem mérete nincs explicit módon beállítva, az a tartalmára méretez.
  • A gyermek tartalmak nem lesznek vizuálisan levágva, ha nagyobbak, mint a panel.
  • A gyermektartalmakat nem korlátozza a panel határai.
  • Rács A rács támogatja a gyerekelemek rugalmas átméretezését. Kód- vagy vizualizációállapotokkal áthelyezheti és újrarendelheti az elemeket.
  • Az elemek sorba és oszlopba vannak rendezve a Grid.Row és a Grid.Column csatolt tulajdonságok használatával.
  • Az elemek több sort és oszlopot is átfoghatnak a Grid.RowSpan és a Grid.ColumnSpan csatolt tulajdonságok használatával.
  • A HorizontalAlignment/VerticalAlignment stretch értékeit a rendszer tiszteletben tartja. Ha egy elem mérete nincs explicit módon beállítva, az a rácscellában lévő szabad terület kitöltéséhez nyúlik.
  • A gyermektartalom vizuálisan ki van vágva, ha nagyobb, mint a panel.
  • A tartalom méretét a panel határai korlátozzák, ezért a görgethető tartalom szükség esetén görgetősávokat jelenít meg.
  • RelativePanel
  • Az elemek a panel széléhez vagy közepéhez, valamint egymáshoz képest vannak elrendezve.
  • Az elemek különböző csatolt tulajdonságokkal vannak elhelyezve, amelyek a panelbeli igazítást, valamint a testvérelemek igazítását és pozícióját szabályozzák.
  • A HorizontalAlignment/VerticalAlignment nyújtás értékeit a rendszer figyelmen kívül hagyja, kivéve, ha a RelativePanel az igazításhoz csatolt tulajdonságok miatt nyújtást okoz (például egy elem a panel jobb és bal széléhez is igazodik). Ha egy elem mérete nincs explicit módon beállítva, és nem feszített, akkor a mérete a tartalmához igazodik.
  • A gyermektartalom vizuálisan ki van vágva, ha nagyobb, mint a panel.
  • A tartalom méretét a panel határai korlátozzák, ezért a görgethető tartalom szükség esetén görgetősávokat jelenít meg.
  • StackPanel
  • Az elemek egyetlen sorban halmozódnak fel függőlegesen vagy vízszintesen.
  • A HorizontalAlignment/VerticalAlignment stretch értékeit a Tájolás tulajdonságmal ellentétes irányban kell figyelembe venni. Ha egy elem mérete nincs explicit módon beállítva, az a rendelkezésre álló szélesség kitöltéséhez (vagy vízszintes tájolás esetén magassághoz) nyúlik. A Tájolás tulajdonság által megadott irányban egy elem mérete a tartalmához igazodik.
  • A gyermektartalom vizuálisan ki van vágva, ha nagyobb, mint a panel.
  • A tartalom méretét nem korlátozza a panel a Tájolás tulajdonság által megadott irányban, ezért a görgethető tartalom túlnyúlik a panel határain, és nem jeleníti meg a görgetősávokat. A görgetősávok megjelenítéséhez kifejezetten korlátoznia kell a gyermektartalom magasságát (vagy szélességét).
  • VariableSizedWrapGrid
  • Az elemek olyan sorokba vagy oszlopokba vannak rendezve, amelyek automatikusan új sorba vagy oszlopba törnek a MaximumRowsOrColumns érték elérésekor.
  • Azt, hogy az elemek sorokba vagy oszlopokba vannak-e rendezve, a Tájolás tulajdonság határozza meg.
  • Az elemek több sort és oszlopot is átfoghatnak a VariableSizedWrapGrid.RowSpan és a VariableSizedWrapGrid.ColumnSpan csatolt tulajdonságok használatával.
  • A HorizontalAlignment és a VerticalAlignment stretch értékei figyelmen kívül lesznek hagyva. Az elemek mérete az ItemHeight és az ItemWidth tulajdonságok szerint van megadva. Ha ezek a tulajdonságok nincsenek beállítva, akkor az első cella méretéből veszik az értékeiket.
  • A gyermektartalom vizuálisan ki van vágva, ha nagyobb, mint a panel.
  • A tartalom méretét a panel határai korlátozzák, ezért a görgethető tartalom szükség esetén görgetősávokat jelenít meg.
  • A panelekre vonatkozó részletes információkért és példákért lásd: Elrendezéspanelek.

    Az elrendezési panelek lehetővé teszik a felhasználói felület logikai vezérlőcsoportokba rendezését. Ha a megfelelő tulajdonságbeállításokkal használja őket, támogatást kap a felhasználói felület elemeinek automatikus átméretezéséhez, áthelyezéséhez és újrafolytatásához. A felhasználói felület legtöbb elrendezésének azonban további módosításra van szüksége, ha az ablak méretében jelentős változások történnek. Ehhez használhat vizualizációs állapotokat.

    Adaptív elrendezések vizualizációs állapotokkal és állapotindítókkal

    Vizualizációs állapotok használatával jelentős módosításokat végezhet a felhasználói felületen az ablakméret vagy más módosítások alapján.

    Ha az alkalmazásablak egy bizonyos mennyiségnél nagyobb méretűre nő vagy zsugorodik, érdemes lehet módosítani az elrendezés tulajdonságait a felhasználói felület szakaszainak áthelyezéséhez, átméretezéséhez, átcsordulásához, megjelenítéséhez vagy cseréjéhez. A felhasználói felület különböző vizualizációs állapotait definiálhatja, és alkalmazhatja őket, amikor az ablak szélessége vagy az ablak magassága átlép egy megadott küszöbértéket.

    A VisualState olyan tulajdonságértékeket határoz meg, amelyek egy adott állapotban lévő elemre vonatkoznak. Vizualizációs állapotokat csoportosíthat egy VisualStateManagerben , amely a megfelelő VisualState-t alkalmazza a megadott feltételek teljesülésekor. Az AdaptiveTrigger segítségével egyszerűen beállíthatja azt a küszöbértéket (más néven töréspontot), ahol az állapot XAML-ben van alkalmazva. Vagy meghívhatja a VisualStateManager.GoToState metódust a kódban a vizualizáció állapotának alkalmazásához. A következő szakaszok mindkét módszerre példákat mutatnak be.

    Vizualizációállapotok beállítása kódban

    Vizualizációs állapot kódból való alkalmazásához hívja meg a VisualStateManager.GoToState metódust . Ha például egy állapotot szeretne alkalmazni, amikor az alkalmazásablak egy adott méretű, kezelje a SizeChanged eseményt , és hívja meg a GoToState-ot a megfelelő állapot alkalmazásához.

    Itt egy VisualStateGroup két VisualState-definíciót tartalmaz. Az első, DefaultState, üres. Alkalmazásakor az XAML lapon definiált értékek lesznek alkalmazva. A második, WideStatea SplitViewDisplayMode tulajdonságát inline-ra módosítja, és megnyitja a panelt. Ez az állapot a SizeChanged eseménykezelőben lesz alkalmazva, ha az ablak szélessége nagyobb, mint 640 tényleges képpont.

    Megjegyzés:

    A Windows nem biztosít módot arra, hogy az alkalmazás észlelje azt az eszközt, amelyen az alkalmazás fut. Meg tudja állapítani a tényleges felbontást és az alkalmazás számára rendelkezésre álló képernyőterületet (az alkalmazás ablakának méretét). Javasoljuk, hogy a képernyőméretekhez és töréspontokhoz definiálja a vizualizációs állapotokat.

    <Page ...
        SizeChanged="Page_SizeChanged">
        <Grid>
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup>
                    <VisualState x:Name="DefaultState">
                            <Storyboard>
                            </Storyboard>
                        </VisualState>
    
                    <VisualState x:Name="WideState">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames
                                Storyboard.TargetProperty="SplitView.DisplayMode"
                                Storyboard.TargetName="mySplitView">
                                <DiscreteObjectKeyFrame KeyTime="0">
                                    <DiscreteObjectKeyFrame.Value>
                                        <SplitViewDisplayMode>Inline</SplitViewDisplayMode>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames
                                Storyboard.TargetProperty="SplitView.IsPaneOpen"
                                Storyboard.TargetName="mySplitView">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="True"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
    
            <SplitView x:Name="mySplitView" DisplayMode="CompactInline"
                       IsPaneOpen="False" CompactPaneLength="20">
                <!-- SplitView content -->
    
                <SplitView.Pane>
                    <!-- Pane content -->
                </SplitView.Pane>
            </SplitView>
        </Grid>
    </Page>
    
    private void Page_SizeChanged(object sender, Microsoft.UI.Xaml.SizeChangedEventArgs e)
    {
        if (e.Size.Width > 640)
            VisualStateManager.GoToState(this, "WideState", false);
        else
            VisualStateManager.GoToState(this, "DefaultState", false);
    }
    
    // YourPage.h
    void Page_SizeChanged(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::SizeChangedEventArgs const& e);
    
    // YourPage.cpp
    void YourPage::Page_SizeChanged(IInspectable const& sender, SizeChangedEventArgs const& e)
    {
        if (e.NewSize.Width > 640)
            VisualStateManager::GoToState(*this, "WideState", false);
        else
            VisualStateManager::GoToState(*this, "DefaultState", false);
    }
    
    

    Vizualizációs állapotok beállítása XAML jelölésben

    A Windows 10 előtt a VisualState-definíciók Storyboard objektumokat igényeltek a tulajdonságmódosításokhoz, és az állapot alkalmazásához meg kellett hívnia GoToState kódban. Ez az előző példában látható. Továbbra is sok példát fog látni, amelyek ezt a szintaxist használják, vagy meglévő kóddal rendelkezik, amely ezt használja.

    A Windows 10-től kezdve az itt látható egyszerűsített Setter szintaxist használhatja, és az állapot alkalmazásához használhatja a StateTriggert az XAML jelölésben. Az állapotindítókkal egyszerű szabályokat hozhat létre, amelyek automatikusan aktiválják a vizuális állapot változásait egy alkalmazáseseményre válaszul.

    Ez a példa ugyanazt teszi, mint az előző példában, de a tulajdonságváltozások definiálásához a Storyboard helyett az egyszerűsített Setter szintaxist használja. A GoToState meghívása helyett pedig a beépített AdaptiveTrigger állapot-eseményindítót használja az állapot alkalmazásához. Állapotindítók használatakor nem kell üreset DefaultStatedefiniálnia. A rendszer automatikusan újra alkalmazza az alapértelmezett beállításokat, ha az állapotindító feltételei már nem teljesülnek.

    <Page ...>
        <Grid>
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup>
                    <VisualState>
                        <VisualState.StateTriggers>
                            <!-- VisualState to be triggered when the
                                 window width is >=640 effective pixels. -->
                            <AdaptiveTrigger MinWindowWidth="640" />
                        </VisualState.StateTriggers>
    
                        <VisualState.Setters>
                            <Setter Target="mySplitView.DisplayMode" Value="Inline"/>
                            <Setter Target="mySplitView.IsPaneOpen" Value="True"/>
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
    
            <SplitView x:Name="mySplitView" DisplayMode="CompactInline"
                       IsPaneOpen="False" CompactPaneLength="20">
                <!-- SplitView content -->
    
                <SplitView.Pane>
                    <!-- Pane content -->
                </SplitView.Pane>
            </SplitView>
        </Grid>
    </Page>
    

    Fontos

    Az előző példában a VisualStateManager.VisualStateGroups csatolt tulajdonság a Rács elemen van beállítva. StateTriggers használatakor mindig győződjön meg arról, hogy a VisualStateGroups a gyökér első gyermekéhez van csatolva, hogy az eseményindítók automatikusan érvénybe léphessenek. (Itt a Rács a gyökéroldal elem első gyermeke.)

    Csatolt tulajdonság szintaxisa

    A VisualState-ban általában egy vezérlőtulajdonság vagy a vezérlőt tartalmazó panel egyik csatolt tulajdonságának értékét állítja be. Csatolt tulajdonság beállításakor használjon zárójeleket a csatolt tulajdonság neve körül.

    Ez a példa bemutatja, hogyan állíthatja be a RelativePanel.AlignHorizontalCenterWithPanel csatolt tulajdonságot egy TextBox nevű myTextBoxszövegmezőn. Az első XAML az ObjectAnimationUsingKeyFrames szintaxist, a második pedig a Setter szintaxist használja.

    <!-- Set an attached property using ObjectAnimationUsingKeyFrames. -->
    <ObjectAnimationUsingKeyFrames
        Storyboard.TargetProperty="(RelativePanel.AlignHorizontalCenterWithPanel)"
        Storyboard.TargetName="myTextBox">
        <DiscreteObjectKeyFrame KeyTime="0" Value="True"/>
    </ObjectAnimationUsingKeyFrames>
    
    <!-- Set an attached property using Setter. -->
    <Setter Target="myTextBox.(RelativePanel.AlignHorizontalCenterWithPanel)" Value="True"/>
    

    Egyéni állapot eseményindítói

    A StateTrigger osztályt kiterjesztheti egyéni eseményindítók létrehozására számos forgatókönyvhöz. Létrehozhat például egy StateTriggert, amellyel különböző állapotokat indíthat el a bemeneti típus alapján, majd növelheti a vezérlőelemek margóit, ha a bemeneti típus érintéses. Vagy hozzon létre egy StateTriggert, amely különböző állapotokat alkalmaz az alkalmazás által futtatott eszközcsalád alapján. Ha például egyéni eseményindítókat szeretne létrehozni, és hogyan hozhat létre optimalizált felhasználói felületi szolgáltatásokat egyetlen XAML-nézetben, tekintse meg a State eseményindítók mintáját.

    Vizualizációs állapotok és stílusok

    A stíluserőforrások vizualizációs állapotokban való használatával több vezérlőelemre is alkalmazhat tulajdonságmódosításokat. A stílusok használatáról további információt a Stílusvezérlők című témakörben talál.

    Ebben az egyszerűsített XAML-ben az állapot-triggerek mintájából egy Stílus erőforrást egy gombra alkalmaznak, hogy hozzáigazítsák a méretet és a margókat az egér- vagy érintésalapú bevitelhez. A teljes kód és az egyéni állapot-eseményindító definíciója: State triggerek minta.

    <Page ... >
        <Page.Resources>
            <!-- Styles to be used for mouse vs. touch/pen hit targets -->
            <Style x:Key="MouseStyle" TargetType="Rectangle">
                <Setter Property="Margin" Value="5" />
                <Setter Property="Height" Value="20" />
                <Setter Property="Width" Value="20" />
            </Style>
            <Style x:Key="TouchPenStyle" TargetType="Rectangle">
                <Setter Property="Margin" Value="15" />
                <Setter Property="Height" Value="40" />
                <Setter Property="Width" Value="40" />
            </Style>
        </Page.Resources>
    
        <RelativePanel>
            <!-- ... -->
            <Button Content="Color Palette Button" x:Name="MenuButton">
                <Button.Flyout>
                    <Flyout Placement="Bottom">
                        <RelativePanel>
                            <Rectangle Name="BlueRect" Fill="Blue"/>
                            <Rectangle Name="GreenRect" Fill="Green" RelativePanel.RightOf="BlueRect" />
                            <!-- ... -->
                        </RelativePanel>
                    </Flyout>
                </Button.Flyout>
            </Button>
            <!-- ... -->
        </RelativePanel>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="InputTypeStates">
                <!-- Second set of VisualStates for building responsive UI optimized for input type.
                     Take a look at InputTypeTrigger.cs class in CustomTriggers folder to see how this is implemented. -->
                <VisualState>
                    <VisualState.StateTriggers>
                        <!-- This trigger indicates that this VisualState is to be applied when MenuButton is invoked using a mouse. -->
                        <triggers:InputTypeTrigger TargetElement="{x:Bind MenuButton}" PointerType="Mouse" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="BlueRect.Style" Value="{StaticResource MouseStyle}" />
                        <Setter Target="GreenRect.Style" Value="{StaticResource MouseStyle}" />
                        <!-- ... -->
                    </VisualState.Setters>
                </VisualState>
                <VisualState>
                    <VisualState.StateTriggers>
                        <!-- Multiple trigger statements can be declared in the following way to imply OR usage.
                             For example, the following statements indicate that this VisualState is to be applied when MenuButton is invoked using Touch OR Pen.-->
                        <triggers:InputTypeTrigger TargetElement="{x:Bind MenuButton}" PointerType="Touch" />
                        <triggers:InputTypeTrigger TargetElement="{x:Bind MenuButton}" PointerType="Pen" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="BlueRect.Style" Value="{StaticResource TouchPenStyle}" />
                        <Setter Target="GreenRect.Style" Value="{StaticResource TouchPenStyle}" />
                        <!-- ... -->
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Page>