WPF 標準コントロールデモアプリ › Viewbox

Viewbox Layout

Viewbox は、1 つの子を子自身の大きさでレイアウトしてから、Viewbox の持つ領域に合わせて拡大縮小します。

子は自分の大きさでレイアウトされてから拡大縮小される

Viewbox は Decorator を継承しているので、子は 1 つ(Child)です。子は無限の大きさ(Infinity × Infinity)で測られるので、自分の本来の大きさになります。デモアプリのラベルは 72.34 × 57.96 でした。Viewbox はこの大きさを拡大縮小します。子自身の ActualWidth と ActualHeight は本来の大きさのままで、拡大縮小されるのは描画だけです。表示上の大きさは、ActualWidth ではなく TransformToAncestor で読みます。

既定値は Stretch="Uniform" と StretchDirection="Both" です。デモアプリはここから始まりません。コンボボックスが列挙型の最初の値の None と UpOnly で始まるので、Stretch を None 以外にするまでラベルは拡大縮小されません。

条件 計測値
基底クラス / 既定値: Stretch、StretchDirection Decorator / Uniform, Both
デモのコンボボックスの最初の項目(列挙値の順): Stretch / StretchDirection None / UpOnly
300 x 100 の Viewbox で子に渡される大きさ / デモの Label の本来の大きさ Infinity x Infinity / 72.34 x 57.96
UniformToFill 300 x 100: Label の位置と大きさ / Viewbox のクリップ / 高さ 100 の 5 下のヒット x=150 y=100 w=300 h=240.35 / 300 x 100 / (なし)
Uniform、高さ 100 の横の StackPanel の中: 拡大率 1.73, 1.73

型、既定値、測り方、切り抜き。.NET 10 / Windows 11 で計測。

Stretch ごとの倍率

300 × 100 の領域で、デモアプリのラベルは、Uniform で縦横とも 1.73 倍(高さに合わせる)、UniformToFill で縦横とも 4.15 倍(幅に合わせる)、Fill で横 4.15 倍・縦 1.73 倍になって形が変わりました。None は 1 倍のままでした。

UniformToFill では、収まらない部分は切れます。300 × 100 の Viewbox で、ラベルは Viewbox の上端から 300 × 240.35 になり、Viewbox のレイアウト上の高さ 100 より 5 下のヒットテストでは何も当たりませんでした。Viewbox のレイアウトのクリップは 300 × 100 でした。全体を見せる必要がある内容には UniformToFill を使いません。

拡大か縮小か:StretchDirection

StretchDirection は、子を拡大してよいか、縮小してよいか、両方かを決めます。ラベルが拡大される 300 × 100 の領域では、DownOnly でどの Stretch も 1 倍のままでした。ラベルが縮小される 40 × 20 の領域では、UpOnly でどの Stretch も 1 倍のままで、ラベルは領域より大きくなりました。Both は、当てはまる方向と同じ倍率になりました。縮めても大きくはしないなら DownOnly を使います。大きなウィンドウで文字が大きくなりすぎるのを防げます。

Stretch 領域 UpOnly DownOnly Both
None 300 x 100 1, 1 1, 1 1, 1
None 40 x 20 1, 1 1, 1 1, 1
Fill 300 x 100 4.15, 1.73 1, 1 4.15, 1.73
Fill 40 x 20 1, 1 0.55, 0.35 0.55, 0.35
Uniform 300 x 100 1.73, 1.73 1, 1 1.73, 1.73
Uniform 40 x 20 1, 1 0.35, 0.35 0.35, 0.35
UniformToFill 300 x 100 4.15, 4.15 1, 1 4.15, 4.15
UniformToFill 40 x 20 1, 1 0.55, 0.55 0.55, 0.55

Stretch、領域、StretchDirection ごとの倍率(横, 縦)。.NET 10 / Windows 11 で計測。

拡大縮小には大きさの制限が要る

幅に制限のない、高さ 100 の横の StackPanel の中では、Uniform の Viewbox はラベルを高さだけに合わせて 1.73 倍にしました。縦横の両方に合わせたいなら、Viewbox の大きさを両方向で限ります。

デモアプリで試す

デモアプリの Viewbox のページ。左にコントロールの一覧、右に最初の節の Stretch / StretchDirection

デモアプリの Viewbox のページには、Stretch と StretchDirection の 1 つの欄があります。欄の下の「Show Code」リンクで、その XAML を表示できます。次の XAML は、その欄(ViewboxUsageControl.xaml)から、スタイルと周囲の GroupBox を省き、名前空間の宣言を加えたものです。デモアプリでは Viewbox はウィンドウの結果の領域いっぱいに置かれますが、このページの計測では Viewbox の大きさを固定しました(300 × 100 と 40 × 20)。markupextensions はデモアプリ独自のマークアップ拡張の接頭辞です。

<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:markupextensions="clr-namespace:WPFStandardControlDemoApp.Common.MarkupExtensions">
  <ComboBox x:Name="StretchComboBox"
            DisplayMemberPath="Name"
            ItemsSource="{markupextensions:EnumBindingSource EnumType=Stretch}"
            SelectedValuePath="Value" SelectedIndex="0" />
  <ComboBox x:Name="StretchDirectionComboBox"
            DisplayMemberPath="Name"
            ItemsSource="{markupextensions:EnumBindingSource EnumType=StretchDirection}"
            SelectedValuePath="Value" SelectedIndex="0" />

  <Viewbox x:Name="StretchViewBox"
           Stretch="{Binding SelectedValue, ElementName=StretchComboBox}"
           StretchDirection="{Binding SelectedValue, ElementName=StretchDirectionComboBox}">
    <Label Padding="20" BorderBrush="Black" BorderThickness="1" Content="Item1" />
  </Viewbox>
</StackPanel>

関連するコントロールと記事

ソースコードと計測の方法

このページの挙動の記述は、すべて .NET 10 / Windows 11 で実際に動かして確かめたものです。計測には、このサイトのスクリーンショット生成ツールの ViewboxDemoScene を使い、デモアプリと同じラベル(Padding 20、枠 1)で試しました。倍率は、Viewbox から見たラベルの大きさを、ラベル自身の大きさで割った値です。大きさは、計測したマシンでの値です。

GitHub で Viewbox のソースコードを見る →