2 ペイン ビューは、リスト/詳細ビューなど、2 つの異なるコンテンツ領域を持つアプリの表示を管理するのに役立つレイアウト コントロールです。
これは適切なコントロールですか?
コンテンツの 2 つの異なるが関連する領域があり、次のような場合は、2 ペイン ビューを使用します。
- ウィンドウに最適なサイズに合わせて、コンテンツの再配置とサイズ変更が自動的に行われます。
- コンテンツの 2 つ目の領域は、使用できる空間に応じて表示または非表示にする必要があります。
コンテンツの 2 つの領域を表示する必要があるが、2 ペイン ビューで提供されるサイズ変更と再配置が必要ない場合は、代わりに 分割ビュー を使用することを検討してください。
ナビゲーション オプションの場合は、 ナビゲーション ビューを使用します。
しくみ
2 ペイン ビューには、コンテンツが配置される 2 つのペインがあります。 ウィンドウに使用できる空間に応じて、ペインのサイズと配置が調整されます。 使用できるペインのレイアウトは、TwoPaneViewMode 列挙体によって定義されます。
| 列挙値 | 説明 |
|---|---|
SinglePane |
PanePriority プロパティの指定に従い、1 つのペインのみが表示されます。 |
Wide |
WideModeConfiguration プロパティの指定に従い、ペインが横並びで表示されるか、単一のペインが表示されます。 |
Tall |
TallModeConfiguration プロパティの指定に従い、ペインが上下に表示されるか、単一のペインが表示されます。 |
ワイド モードのアプリ。
背の高いモードのアプリ。
2 ペイン ビューを構成するには、PanePriority を設定して、1 つのペインのみに空間がある場合に表示するペインを指定します。 次に、Pane1 を縦長ウィンドウの上または下に表示するか、横長ウィンドウの左または右に表示するかを指定します。
2 ペイン ビューでは、ペインのサイズと配置が処理されますが、ペイン内のコンテンツをサイズと向きの変更に適応させる必要があります。 アダプティブ UI の作成の詳細については、「XAML でのレスポンシブ レイアウト」と「レイアウト パネル」を参照してください。
2 ペイン ビューを作成する
- 重要な API:TwoPaneView クラス
この XAML では、基本的な TwoPaneViewを作成する方法を示します。
<TwoPaneView>
<TwoPaneView.Pane1>
<Grid Background="{ThemeResource LayerFillColorDefaultBrush}">
<TextBlock Text="Pane 1" Margin="24"
Style="{ThemeResource HeaderTextBlockStyle}"/>
</Grid>
</TwoPaneView.Pane1>
<TwoPaneView.Pane2>
<Grid Background="{ThemeResource LayerFillColorAltBrush}">
<TextBlock Text="Pane 2" Margin="24"
Style="{ThemeResource HeaderTextBlockStyle}"/>
</Grid>
</TwoPaneView.Pane2>
</TwoPaneView>
TwoPaneView は、ページ レイアウトのルート要素である必要はありません。 実際、アプリの全体的なナビゲーションを提供する NavigationView コントロール内で使用することがよくあります。
TwoPaneViewは、XAML ツリー内のどこにあるかに関係なく、適切に調整されます。
ペインにコンテンツを追加する
2 ペイン ビューの各ペインには、1 つの XAML UIElement を保持できます。 コンテンツを追加するには、通常、各ペインに XAML レイアウト パネルを配置し、他のコントロールとコンテンツをパネルに追加します。 ペインのサイズを変更し、横長モードと縦長モードを切り替えることができるため、各ペインのコンテンツがこのような変更に適応できることを確認する必要があります。 アダプティブ UI の作成の詳細については、「XAML でのレスポンシブ レイアウト」と「レイアウト パネル」を参照してください。
この例では、前に示した単純な画像/情報アプリ UI を作成します。 コンテンツは、使用可能な領域の量に応じて、2 つのペインに表示することも、1 つのペインにまとめることもできます。 (ペインのスペースが 1 つしかない場合は、Pane2 のコンテンツを Pane1 に移動し、ユーザーがスクロールして非表示のコンテンツを表示できるようにします。このコードについては、「モード変更への対応」セクションで後述します。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<CommandBar DefaultLabelPosition="Right">
<AppBarButton x:Name="Share" Icon="Share" Label="Share" Click="Share_Click"/>
<AppBarButton x:Name="Print" Icon="Print" Label="Print" Click="Print_Click"/>
</CommandBar>
<TwoPaneView
x:Name="MyTwoPaneView"
Grid.Row="1"
MinWideModeWidth="959"
MinTallModeHeight="863"
ModeChanged="TwoPaneView_ModeChanged">
<TwoPaneView.Pane1>
<Grid x:Name="Pane1Root">
<ScrollViewer>
<StackPanel x:Name="Pane1StackPanel">
<Image Source="Assets\LandscapeImage8.jpg"
VerticalAlignment="Top" HorizontalAlignment="Center"
Margin="16,0"/>
</StackPanel>
</ScrollViewer>
</Grid>
</TwoPaneView.Pane1>
<TwoPaneView.Pane2
<Grid x:Name="Pane2Root">
<ScrollViewer x:Name="DetailsContent">
<StackPanel Padding="16">
<TextBlock Text="Mountain.jpg" MaxLines="1"
Style="{ThemeResource HeaderTextBlockStyle}"/>
<TextBlock Text="Date Taken:"
Style="{ThemeResource SubheaderTextBlockStyle}"
Margin="0,24,0,0"/>
<TextBlock Text="8/29/2019 9:55am"
Style="{ThemeResource SubtitleTextBlockStyle}"/>
<TextBlock Text="Dimensions:"
Style="{ThemeResource SubheaderTextBlockStyle}"
Margin="0,24,0,0"/>
<TextBlock Text="800x536"
Style="{ThemeResource SubtitleTextBlockStyle}"/>
<TextBlock Text="Resolution:"
Style="{ThemeResource SubheaderTextBlockStyle}"
Margin="0,24,0,0"/>
<TextBlock Text="96 dpi"
Style="{ThemeResource SubtitleTextBlockStyle}"/>
<TextBlock Text="Description:"
Style="{ThemeResource SubheaderTextBlockStyle}"
Margin="0,24,0,0"/>
<TextBlock Text="Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna."
Style="{ThemeResource SubtitleTextBlockStyle}"
TextWrapping="Wrap"/>
</StackPanel>
</ScrollViewer>
</Grid>
</TwoPaneView.Pane2>
</TwoPaneView>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="TwoPaneViewStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Wide">
<VisualState.Setters>
<Setter Target="MyTwoPaneView.Pane1Length"
Value="2*"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
表示するペインを指定する
2 ペイン ビューで表示できるペインが 1 つだけの場合、PanePriority プロパティを使用して、表示するペインを決定します。 既定では、PanePriority は Pane1 に設定されています。 XAML またはコードでこのプロパティを設定する方法を次に示します。
<TwoPaneView x:Name="MyTwoPaneView" PanePriority="Pane2">
MyTwoPaneView.PanePriority = TwoPaneViewPriority.Pane2;
ペインのサイズ設定
ペインのサイズは、 Pane1Length プロパティと Pane2Length プロパティによって決まります。 これらには、auto および star(*) のサイズ設定をサポートする GridLength 値が使用されます。 自動サイズ設定と比例サイズ設定の詳細については、「XAML でのレスポンシブ レイアウト」の「レイアウト プロパティ」を参照してください。
既定では、Pane1Length は Auto に設定され、コンテンツに合わせてサイズが自動調整されます。
Pane2Length は * に設定され、残りのすべての空間が使用されます。
既定のサイズ設定のペイン
この既定値は、Pane1 に項目の一覧があり、Pane2 に多くの詳細がある、リストと詳細からなる一般的なレイアウトに役立ちます。 ただし、コンテンツに応じて、異なる方法で空間を分割することをお勧めします。 ここでは、Pane1Length が 2* に設定されているため、Pane2の 2 倍の空間が使用されます。
<TwoPaneView x:Name="MyTwoPaneView" Pane1Length="2*">
ペインサイズ 2* と *
自動サイズ設定を使用するようにウィンドウを設定する場合は、ウィンドウのコンテンツを保持する Panel の高さと幅を設定することで、サイズを制御できます。 この場合は、 ModeChanged イベントを処理し、現在のモードに合わせてコンテンツの高さと幅の制約を設定する必要があります。
横長モードまたは縦長モードで表示する
シングル スクリーン上では、2 ペイン ビューのディスプレイの Mode は MinWideModeWidth および MinTallModeHeight プロパティによって決まります。 どちらのプロパティも、既定値は NavigationView.CompactThresholdWidth と同じ 641 px です。
次の表は、TwoPaneViewのHeightとWidthが使用される表示モードを決定する方法を示しています。
| TwoPaneView 条件 | モード |
|---|---|
Width > MinWideModeWidth |
Wide モードが使用されます |
Width
<= MinWideModeWidth および Height>MinTallModeHeight |
Tall モードが使用されます |
Width
<= MinWideModeWidth および Height<= MinTallModeHeight |
SinglePane モードが使用されます |
横長構成のオプション
MinWideModeWidth を使うと、2 ペイン ビューが横長モードに切り替わるタイミングを制御できます。 使用可能な領域が MinWideModeWidth プロパティより広い場合、2 ペイン ビューはWide モードになります。 既定値は 641 px ですが、任意の値に変更できます。 一般的に、このプロパティは、ペインの最小の幅として使用する値に設定することをお勧めします。
2 ペイン ビューが横長モードの場合、WideModeConfiguration プロパティによって、表示される内容が決まります。
| 列挙値 | 説明 |
|---|---|
SinglePane |
シングル ペイン (PanePriority によって決まります)。 ペインは、TwoPaneView のサイズ全体を占有します (つまり、両方向に比例サイズ設定です)。 |
LeftRight |
左側に Pane1、右側に Pane2。 両方のペインは縦方向に比例サイズ設定、Pane1 の幅は自動サイズ設定、Pane2 の幅は比例サイズ設定です。 |
RightLeft |
右側に Pane1、左側に Pane2。 両方のペインは縦方向に比例サイズ設定、Pane2 の幅は自動サイズ設定、Pane1 の幅は比例サイズ設定です。 |
既定の設定は LeftRight です。
| 左右 | 右左 |
|---|---|
|
|
注
デバイスが右から左 (RTL) 言語を使用する場合、2 ペイン ビューは自動的に順序を入れ替えます。 RightLeft は LeftRightとしてレンダリングされ、 LeftRight は RightLeftとしてレンダリングされます。
縦長構成のオプション
2 ペイン ビューは、使用可能な領域がMinWideModeWidthよりも狭く、高さがMinTallModeHeightよりも高い場合に、Tall モードになります。 既定値は 641 px ですが、任意の値に変更できます。 一般的に、このプロパティは、ペインの最小の高さとして使用する値に設定することをお勧めします。
2 ペイン ビューが縦長モードの場合、TallModeConfiguration プロパティによって、表示される内容が決まります。
| 列挙値 | 説明 |
|---|---|
SinglePane |
シングル ペイン (PanePriority によって決まります)。 ペインは、TwoPaneView のサイズ全体を占有します (つまり、両方向に比例サイズ設定です)。 |
TopBottom |
上側に Pane1、下側に Pane2。 両方のペインは横方向に比例サイズ設定、Pane1 の高さは自動サイズ設定、Pane2 の高さは比例サイズ設定です。 |
BottomTop |
下側に Pane1、上側に Pane2。 両方のペインは横方向に比例サイズ設定、Pane2 の高さは自動サイズ設定、Pane1 の高さは比例サイズ設定です。 |
既定値は、TopBottom です。
| トップボトム | 下から上 |
|---|---|
|
|
MinWideModeWidth と MinTallModeHeight の特別な値
MinWideModeWidth プロパティを使用すると、2 ペイン ビューが Wide モードに入らないようにすることができます。MinWideModeWidthを Double.PositiveInfinity に設定するだけです。
MinTallModeHeightを Double.PositiveInfinity に設定すると、2 ペイン ビューがTall モードに入らないようにします。
MinTallModeHeight を 0 に設定すると、2 ペイン ビューが SinglePane モードになるのを防ぎます。
モードの変更への対応
読み取り専用の Mode プロパティを使用して現在の表示モードを取得できます。 2 ペイン ビューに表示されるペインが変わるたびに、更新されたコンテンツがレンダリングされる前に ModeChanged イベントが発生します。 このイベントを処理して、表示モードの変更に対応できます。
重要
ModeChanged イベントは、ページが最初に読み込まれるときには発生しないので、既定の XAML は最初に読み込まれたときに表示される UI を表す必要があります。
このイベントを使用する方法の 1 つは、ユーザーが SinglePane モードですべてのコンテンツを表示できるようにアプリの UI を更新することです。 たとえば、サンプル アプリにはプライマリ ペイン (画像) と情報ペインがあります。
"縦長モード"
1 つのペインを表示するだけの空間しかない場合は、ユーザーがスクロールしてすべてのコンテンツを表示できるように、Pane2 のコンテンツを Pane1 に移動します。 次のようになります。
SinglePane モード
MinWideModeWidth および MinTallModeHeight プロパティによって、表示モードを変更するタイミングが決定するため、これらのプロパティの値を調整すると、ペイン間でコンテンツを移動するタイミングを変更できます。
ModeChanged と Pane1 の間でコンテンツを移動する Pane2 イベント ハンドラー コードを次に示します。 また、 VisualState を設定して、 Wide モードでイメージの幅を制限します。
private void TwoPaneView_ModeChanged(TwoPaneView sender, object args)
{
// Remove details content from it's parent panel.
((Panel)DetailsContent.Parent).Children.Remove(DetailsContent);
// Set Normal visual state.
VisualStateManager.GoToState(this, "Normal", true);
// Single pane
if (sender.Mode == TwoPaneViewMode.SinglePane)
{
// Add the details content to Pane1.
Pane1StackPanel.Children.Add(DetailsContent);
}
// Dual pane.
else
{
// Put details content in Pane2.
Pane2Root.Children.Add(DetailsContent);
// If also in Wide mode, set Wide visual state
// to constrain the width of the image to 2*.
if (sender.Mode == TwoPaneViewMode.Wide)
{
VisualStateManager.GoToState(this, "Wide", true);
}
}
}
UWP と WinUI 2
重要
この記事の情報と例は、 Windows App SDK と WinUI 3 を使用するアプリ向けに最適化されていますが、一般的には WinUI 2 を使用する UWP アプリに適用されます。 プラットフォーム固有の情報と例については、UWP API リファレンスを参照してください。
このセクションには、UWP または WinUI 2 アプリでコントロールを使用するために必要な情報が含まれています。
UWP アプリ用 の TwoPaneView には WinUI 2 が必要です。 インストール手順などの詳細については、「WinUI 2」を参照してください。 このコントロールの API は、Microsoft.UI.Xaml.Controls 名前空間に存在します。
- WinUI 2 Apis:TwoPaneView クラス
WinUI 2 でこの記事のコードを使用するには、XAML のエイリアス (muxcを使用) を使用して、プロジェクトに含まれる Windows UI ライブラリ API を表します。 詳細については、「WinUI 2 の概要」を参照してください。
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
<muxc:TwoPaneView />
関連記事
Windows developer