Expander

Expander コントロールを使用すると、常に表示されるプライマリ コンテンツの一部に関連する、重要度の低いコンテンツの表示と非表示を切り替えることができます。 Header に含まれる項目は常に表示されます。 ユーザーは、ヘッダーを操作することによって、セカンダリ コンテンツが表示されるコンテンツ領域を展開したり折りたたんだりすることができます。 コンテンツ領域が展開されると、他の UI 要素は非表示になります。他の UI に重ねて表示されません。 Expander は、上または下方向に展開できます。

Header および Content の両方の領域には、単純なテキストから複雑な UI レイアウトまで、任意のコンテンツを含めることができます。 たとえば、このコントロールを使用して、項目の追加オプションを表示できます。

展開され、折りたたまれる折りたたまれたエキスパンダー。ヘッダーには

これは適切なコントロールですか?

一部のプライマリ コンテンツを常に表示する必要があるが、関連するセカンダリ コンテンツは、必要になるまで非表示にする場合は、Expander を使用します。 この UI は、一般的に、表示領域が限られている場合、および情報またはオプションをまとめてグループ化できる場合に使用されます。 また、必要になるまでセカンダリ コンテンツを非表示にすると、ユーザーの注意をアプリの最も重要な部分に集中させるのにも役立ちます。

UWP と WinUI 2

重要

この記事の情報と例は、Windows アプリ SDKWinUI 3 を使用するアプリ向けに最適化されていますが、一般に WinUI 2 を使用する UWP アプリに適用されます。 プラットフォーム固有の情報と例については、UWP API リファレンスを参照してください。

このセクションには、UWP または WinUI 2 アプリでコントロールを使用するために必要な情報が含まれています。

UWP アプリの Expander には、Windows UI ライブラリ 2 が必要です。 インストール手順などについて詳しくは、「Windows UI Library (Windows UI ライブラリ)」をご覧ください。 このコントロールの API は 、Microsoft.UI.Xaml.Controls 名前空間に存在します。

WinUI 2 でこの記事のコードを使用するには、XAML のエイリアスを使って (ここでは muxc を使用)、プロジェクトに含まれる Windows UI ライブラリ API を表します。 詳細については、「WinUI 2 の概要」を参照してください。

xmlns:muxc="using:Microsoft.UI.Xaml.Controls"

<muxc:Expander />

Expander を作成する

WinUI 3 ギャラリー アプリには、ほとんどの WinUI 3 コントロールと機能の対話型の例が含まれています。 Microsoft Store からアプリを入手するか、GitHub でソース コードを取得します。

次の例は、既定のスタイルを使用して単純な Expander を作成する方法を示しています。 Header プロパティは、常に表示される要素を定義します。 Content プロパティは、折りたたみおよび展開できる要素を定義します。 この例では、前の図のような外観の Expander を作成します。

<Expander Header="This text is in the header"
               Content="This is in the content"/>

Expander のコンテンツ

ExpanderContent プロパティには、任意のオブジェクトを指定できますが、通常は文字列または UIElementです。 Content プロパティの設定の詳細については、ContentControl クラスの「解説」セクションを参照してください。

次に示すように、親 Expander のコンテンツに入れ子になった Expander コントロールを含め、Expander のコンテンツとして、複雑な対話型の UI を使用できます。

コンテンツ内に入れ子になった 4 つの Expander コントロールを持つ、開いているエキスパンダー。入れ子になった各 Expander コントロールのヘッダーにはラジオ ボタンとテキストがあります

コンテンツの配置

コンテンツを配置するには、Expander コントロールに HorizontalContentAlignment および VerticalContentAlignment プロパティを設定します。 これらのプロパティを設定すると、配置は、ヘッダーではなく展開されたコンテンツにのみ適用されます。

Expander のサイズを制御する

既定では、ヘッダー および コンテンツ の領域のサイズは、その内容に合わせて自動的に設定されます。 望ましくない外観や動作を回避するには、適切な手法を使用して Expander のサイズを制御することが重要です。

コンテンツの幅がヘッダーよりも広い場合、ヘッダーの幅は、展開時にはコンテンツ領域に合わせて拡大され、コンテンツ領域が折りたたまれているときには縮小されます。 展開したとき、または折りたたんだときにコントロールの幅が変更されるのを防ぐには、幅を明示的に設定します。また、コントロールがパネルの子である場合は、HorizontalAlignmentStretch に設定し、レイアウト パネルでサイズ設定を制御できるようにします。

ここでは、一連の関連する Expander コントロールを StackPanelに配置します。 StackPanel 内の各 ExpanderHorizontalAlignment は、StackPanelResources 内の Style を使用して Stretch に設定されています。StackPanel の幅によって Expander コントロールの幅が決まります。

<StackPanel x:Name="ExpanderStack" MaxWidth="600">
    <StackPanel.Resources>
        <Style TargetType="Expander">
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        </Style>
    </StackPanel.Resources>
    <Expander Header="Choose your crust"> ... </Expander>
    <Expander Header="Choose your sauce"> ... </Expander>
    <Expander Header="Choose your toppings"> ... </Expander>
 </StackPanel>

垂直方向に積み上げ、すべて同じ幅の 3 つのエキスパンダー コントロール

[高さ]

Expander では、高さを指定しないでください。 指定すると、コンテンツ領域を折りたたんでも、そのスペースが予約されるため、Expander を使用する意味がなくなります。 展開時のコンテンツ領域のサイズを指定するには、Expander のコンテンツのサイズ寸法を設定します。 必要に応じて、コンテンツの Height を制限し、スクロール可能にすることができます。

スクロール可能なコンテンツ

コンテンツ領域のサイズに対してコンテンツが大きすぎる場合、コンテンツを ScrollViewer にラップして、コンテンツ領域をスクロール可能にすることができます。 Expander コントロールでは、スクロール機能は自動的には提供されません。

ScrollViewerExpander に配置する場合、ScrollViewer コントロールの高さを、コンテンツ領域に必要な高さに設定します。 代わりに ScrollViewer 内のコンテンツの高さの寸法を設定しても、この設定は ScrollViewer によって認識されないため、スクロール可能なコンテンツは提供されません。

次の例は、スクロール可能なテキストをコンテンツとして含む Expander コントロールを作成する方法を示しています。

<Expander Header="Expander with scrollable content">
    <ScrollViewer MaxHeight="200">
        <Grid>
            <TextBlock TextWrapping="Wrap">
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, 
                sed do eiusmod tempor incididunt ut labore et dolore magna
                aliqua. Ut enim ad minim veniam, quis nostrud exercitation
                ullamco laboris nisi ut aliquip ex ea commodo consequat.
                Duis aute irure dolor in reprehenderit in voluptate velit
                esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
                occaecat cupidatat non proident, sunt in culpa qui officia
                deserunt mollit anim id est laborum.
            </TextBlock>
        </Grid>
    </ScrollViewer>
</Expander>

スクロール可能なテキストをコンテンツとして含むエキスパンダー

コンテンツ領域の展開と折りたたみ

既定では、Expander は折りたたまれており、下方向に展開されます。

  • IsExpanded プロパティを true に設定して、コンテンツ領域が最初は展開された状態になるようにします。
  • ExpandDirection プロパティを Up に設定し、コンテンツが上方向に展開されるようにします。
<Expander IsExpanded="True" ExpandDirection="Up">

Expander をプログラムで展開するかまたは折りたたむには、IsExpanded プロパティを設定するか、または Header を操作します。簡易非表示にすることはできません。

ヒント

Flyout や、ComboBox の開いているドロップダウンなどの 一時的な UI は、その外側をクリックまたはタップすると閉じられます。 これは、"簡易非表示" と呼ばれます。 Expander のコンテンツ領域は、一時的と見なされず、他の UI にオーバーレイされないため、簡易非表示はサポートされません。

また、展開および折りたたみイベントを処理して、コンテンツが表示または非表示のときにアクションを実行することもできます。 これらのイベントのいくつかの例を次に示します。

展開イベント

この例では、Expander のグループがあり、一度に 1 つのみが開くようにします。 ユーザーが Expander を開くと、展開 イベントが処理され、ユーザーがクリックしたもの以外のグループ内のすべての Expander コントロールは折りたたまれます。

注意事項

アプリとユーザーエクスペリエンスによっては、ユーザーが別の Expander コントロールを展開したときにコントロールが自動的に折りたたまれるようにする方が便利な場合があります。 しかし、これにより、ユーザーによる制御も失われます。 この動作が役立つ可能性がある場合は、ユーザーが簡単に設定できるオプションにすることを検討してください。

<StackPanel x:Name="ExpanderStack">
    <Expander Header="Choose your crust"
                   Expanding="Expander_Expanding"> ... </Expander>
    <Expander Header="Choose your sauce"
                   Expanding="Expander_Expanding"> ... </Expander>
    <Expander Header="Choose your toppings"
                   Expanding="Expander_Expanding"> ... </Expander>
 </StackPanel>
// Let the user opt out of custom behavior.
private bool _autoCollapse = true;

private void Expander_Expanding(muxc.Expander sender, 
                                muxc.ExpanderExpandingEventArgs args)
{
    if (_autoCollapse == true)
    {
        foreach (muxc.Expander ex in ExpanderStack.Children)
        {
            if (ex != sender && ex.IsExpanded)
                ex.IsExpanded = false;
        }
    }
}

折りたたみイベント

この例では、折りたたみ イベントを処理して、HeaderContentで選択されているオプションの概要を設定します。

次の図は、コンテンツが展開され、オプションが選択されている Expander を示します。

コンテンツ領域に選択したオプションが表示された展開されたエキスパンダー コントロール

折りたたまれると、ユーザーが Expander を開かなくてもオプションを確認できるように、選択されたオプションの概要がヘッダーに表示されます。

ヘッダーに要約された選択したオプションを含む折りたたまれた展開コントロール

<Expander IsExpanded="True"
        Expanding="Expander_Expanding"
        Collapsed="Expander_Collapsed">
    <Expander.Header>
        <Grid>
            <TextBlock Text="Choose your crust"/>
            <TextBlock x:Name="tbCrustSelections"
                       HorizontalAlignment="Right"
                       Style="{StaticResource CaptionTextBlockStyle}"/>
        </Grid>
    </Expander.Header>
    <StackPanel Orientation="Horizontal">
        <RadioButtons x:Name="rbCrustType" SelectedIndex="0">
            <x:String>Classic</x:String>
            <x:String>Whole wheat</x:String>
            <x:String>Gluten free</x:String>
        </RadioButtons>
        <RadioButtons x:Name="rbCrustStyle" SelectedIndex="0" 
                           Margin="48,0,0,0">
            <x:String>Regular</x:String>
            <x:String>Thin</x:String>
            <x:String>Pan</x:String>
            <x:String>Stuffed</x:String>
        </RadioButtons>
    </StackPanel>
</Expander>
private void Expander_Collapsed(muxc.Expander sender, 
                                muxc.ExpanderCollapsedEventArgs args)
{
    // Update the header with options selected in the content.
    tbCrustSelections.Text = rbCrustType.SelectedItem.ToString() +
        ", " + rbCrustStyle.SelectedItem.ToString();
}

軽量なスタイル設定

既定の StyleControlTemplate を変更して、コントロールを固有の外観にすることができます。 利用可能なテーマ リソースの一覧については、Expander API ドキュメントの「コントロール スタイルとテンプレート」セクションを参照してください。 詳細については、スタイル設定コントロールに関する記事の「軽量なスタイル設定」セクションを参照してください。

推奨事項

  • 表示スペースが限られており、ユーザーが要求するまで一部のセカンダリ コンテンツが非表示になる場合は、Expander を使用します。

コード例

この XAML は、この記事の他の部分に示されている Expander コントロールのグループを作成します。 ExpandingCollapsed イベント ハンドラーのコードは、前のセクションでも示されています。

<StackPanel x:Name="ExpanderStack" MaxWidth="600">
    <StackPanel.Resources>
        <Style TargetType="Expander">
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        </Style>
    </StackPanel.Resources>
    <Expander IsExpanded="True"
                   Expanding="Expander_Expanding"
                   Collapsed="Expander_Collapsed">
        <Expander.Header>
            <Grid>
                <TextBlock Text="Choose your crust"/>
                <TextBlock x:Name="tbCrustSelections" 
                           HorizontalAlignment="Right"
        Style="{StaticResource CaptionTextBlockStyle}"/>
            </Grid>
        </Expander.Header>
        <StackPanel Orientation="Horizontal">
            <RadioButtons x:Name="rbCrustType" SelectedIndex="0">
                <x:String>Classic</x:String>
                <x:String>Whole wheat</x:String>
                <x:String>Gluten free</x:String>
            </RadioButtons>
            <RadioButtons x:Name="rbCrustStyle" SelectedIndex="0" 
                   Margin="48,0,0,0">
                <x:String>Regular</x:String>
                <x:String>Thin</x:String>
                <x:String>Pan</x:String>
                <x:String>Stuffed</x:String>
            </RadioButtons>
        </StackPanel>
    </Expander>
    
    <Expander Header="Choose your sauce" Margin="24"
            Expanding="Expander_Expanding">
        <RadioButtons SelectedIndex="0" MaxColumns="2">
            <x:String>Classic red</x:String>
            <x:String>Garlic</x:String>
            <x:String>Pesto</x:String>
            <x:String>Barbecue</x:String>
        </RadioButtons>
    </Expander>

    <Expander Header="Choose your toppings"
                   Expanding="Expander_Expanding">
        <StackPanel>
            <Expander>
                <Expander.Header>
                    <RadioButton GroupName="Toppings" Content="House special"/>
                </Expander.Header>
                <TextBlock Text="Cheese, pepperoni, sausage, black olives, mushrooms"
                           TextWrapping="WrapWholeWords"/>
            </Expander>
            <Expander>
                <Expander.Header>
                    <RadioButton GroupName="Toppings" Content="Vegetarian"/>
                </Expander.Header>
                <TextBlock Text="Cheese, mushrooms, black olives, green peppers, artichoke hearts"
                           TextWrapping="WrapWholeWords"/>
            </Expander>
            <Expander>
                <Expander.Header>
                    <RadioButton GroupName="Toppings" Content="All meat"/>
                </Expander.Header>
                <TextBlock Text="Cheese, pepperoni, sausage, ground beef, salami"
                           TextWrapping="WrapWholeWords"/>
            </Expander>
            <Expander>
                <Expander.Header>
                    <RadioButton GroupName="Toppings" Content="Choose your own"/>
                </Expander.Header>
                <StackPanel Orientation="Horizontal">
                    <StackPanel>
                        <CheckBox Content="Cheese"/>
                        <CheckBox Content="Pepperoni"/>
                        <CheckBox Content="Sausage"/>
                    </StackPanel>
                    <StackPanel>
                        <CheckBox Content="Ground beef"/>
                        <CheckBox Content="Salami"/>
                        <CheckBox Content="Mushroom"/>
                    </StackPanel>
                    <StackPanel>
                        <CheckBox Content="Black olives"/>
                        <CheckBox Content="Green peppers"/>
                        <CheckBox Content="Artichoke hearts"/>
                    </StackPanel>
                </StackPanel>
            </Expander>
        </StackPanel>
    </Expander>
</StackPanel>