Zarovnání obsahu UWP CommandBaru po Anniversary Update

Visual Studio Development WinUI XAML

7 years ago

Ovladací prvek CommandBar získal s Anniversary Updatem novou funkci dynamic overflow, která automaticky upravuje počet zobrazených tlačítek tak, aby se vešly na obrazovku a zbylá tlačítka nechá "přetéct" do sekundárního menu. Tato novinka bohužel přinesla neúmyslné problémy některým vývojářům, kteří používali vlastnost Content pro zobrazení dalšího obsahu na panelu - zarovnání obsahu nyní nefunguje dle očekávání.

Problém

Situaci demonstrujeme na jednoduchém příkladě:

<CommandBar HorizontalContentAlignment="Center">
    <AppBarButton Icon="Accept" />
    <CommandBar.Content>
        <TextBlock Text="My content" />
    </CommandBar.Content>
</CommandBar>

Očekáváme, že obsah panelu bude zarovnaný uprostřed volného místa, které zbývá po umístění tlačítek. A tak tomu také před Anniversary Update bylo. Od verze 14393 SDK ale vlastnost HorizontalContentAlignment ve výchozím stavu není respektována a obsah je zarovnán vlevo.

CommandBar ve výchozím stavu nerespektuje vlastnost HorizontalContentAlignment

Příčina problému

Výchozí šablony ovladacích prvků jsou definovány v souboru XAML resource dictionary na následující cestě: C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.14393.0\Generic\generic.xaml . Pokud v tomto souboru vyhledáte šablonu pro CommandBar , zjistíte, že obsahuje novou skupinu VisualStateGroup :

<VisualStateGroup x:Name="DynamicOverflowStates">
  <VisualState x:Name="DynamicOverflowDisabled"/>
  <VisualState x:Name="DynamicOverflowEnabled">
    <VisualState.Setters>
      <Setter Target="ContentControlColumnDefinition.Width" Value="Auto"/>
      <Setter Target="PrimaryItemsControlColumnDefinition.Width" Value="*"/>
    </VisualState.Setters>
  </VisualState>
</VisualStateGroup>

Jak je z kódu vidět, při povoleném dynamic overflow se mění nastavení velikosti sloupců v rozložení CommandBaru . Ve výchozím visual state (DynamicOverflowDisabled ) je ContentControlColumnDefinition.Width nastavena na * (hvězda) a PrimaryItemsControlColumnDefinition.Width nastavena na Auto . To znamená, že tlačítka napravo zabírají určitou šířku a zbylý prostor je dedikován obsahu Content . Když je dynamic overflow povolen, velikosti sloupců se prohodí. Ovladací prvek nyní nechá sloupec s tlačítky roztáhnout (aby dostupné místo mohl potenciálně využít pro více tlačítek a mohl také spočítat prostor pro ně za běhu aplikace) a sloupec s obsahem dostane už pouze takový prostor, který skutečně potřebuje. To znamená, že s povoleným dynamic overflow bude obsah vždy vypadat jako zarovnaný vlevo, protože jeho sloupec mu nenabízí žádné místo navíc. Od Anniversary Update je dynamic overflow u command baru ve výchozím stavu povolen.

Řešení

Dynamic overflow můžete vypnout pomocí vlastnosti IsDynamicOverflowEnabled. Ačkoliv se poté musíte ujistit, že se tlačítka na panelu zobrazují správně pro všechna rozlišení obrazovky, můžete díky tomu zarovnávat obsah dle potřeby.

<CommandBar HorizontalContentAlignment="Center"
            IsDynamicOverflowEnabled="False">
   <CommandBar.Content>
      <TextBlock Text="Content" />
   </CommandBar.Content>
</CommandBar>

Zakázání dynamic overflow opraví problém se zarovnáním obsahu

Pokud chcete zachovat dynamic overflow, můžete namísto jeho vypnutí okolo vašeho obsahu přidat odsazení (Margin ) tak, aby vypadal zarovnaný. Pravděpodobně bude ale nutné použít Adaptive Triggery aby odsazení vypadalo dobře na každém zařízení.