SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

WPFで、マウスポインタを外すと自動的に隠れるウィンドウを実装する

WPFでツールウィンドウを作成する - AutoHide編

手順5:コントロールのデザイン2 ~ItemsControlの表示設定~

 遂に最終段階です。ItemsControlの中を詳細に見ていきましょう。

<ItemsControl Name="LeftTab" DockPanel.Dock="Left"
  ItemsSource="{TemplateBinding LeftContents}">
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel/>
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <ItemsControl.ItemTemplate>
    ・・・
  </ItemsControl.ItemTemplate>
</ItemsControl>

 ItemsControl内のプロパティでItemsControlの表示方法を指定します。

 ItemsPanelプロパティでは、各アイテムをどのパネルに配置するかを指定します。左右に配置するItemsControlは縦方向のStackPanel、下に配置するItemsControlは横方向のStackPanelを利用します(上のコードでは何も指定していませんが、StackPanelはデフォルトのOrientationがVerticalなので縦方向の配置になります)。

図4 アイテムの配置方向
図4 アイテムの配置方向

 ItemTemplateプロパティは各アイテムをどのような外観で表示するかを指定します。

<ItemsControl.ItemTemplate>
  <DataTemplate>
    <Border BorderBrush="Black" BorderThickness="1">
      <StackPanel>
        <Image Source="{Binding Path=IconUri}" Width="16"
          HorizontalAlignment="Center"/>
        <TextBlock Text="{Binding Path=Title}">
          <TextBlock.LayoutTransform>
            <RotateTransform Angle="90"/>
          </TextBlock.LayoutTransform>
        </TextBlock>
        <Popup Name="LeftPopup"
          PlacementTarget="{Binding ElementName=LeftTab}"
          Placement="Right" IsOpen="True">
          ・・・
        </Popup>
      </StackPanel>
      ・・・
    </Border>
  </DataTemplate>
</ItemsControl.ItemTemplate>

 StackPanelの中にはImageTextBlockがあります。ImageSourceプロパティにIconUriTextBlockTextプロパティにTitleをバインドしています。また、テキストはRotateTransformクラスで90度回転させてから表示しています。

 そして、StackPanelの中にはPopupも入っています。実は、このコントロールでツールウィンドウを表示させています。

 Popupはフローティングコンテンツを表示できる便利なコントロールです。WPFのコントロールでは、ToolTipMenuToolBarComboBoxなどで利用されています。

<Popup Name="LeftPopup"
  PlacementTarget="{Binding ElementName=LeftTab}"
  Placement="Right" IsOpen="True">
  <Border Name="LeftPopupBorder" Width="0"
    Height="{Binding ElementName=MainContent, Path=ActualHeight}"
    rderBrush="Black" BorderThickness="1" Background="Aqua">
    <DockPanel>
      <StackPanel DockPanel.Dock="Top">
        <Grid Background="Black">
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
          </Grid.ColumnDefinitions>
          <TextBlock Grid.Column="0" Text="{Binding Path=Title}"
            Foreground="White"/>
          <Image Grid.Column="1" Source="Image\btnMenu.PNG"/>
          <Image Grid.Column="2" Source="Image\btnAutoHide.PNG"/>
          <Image Grid.Column="3" Source="Image\btnClose.PNG"/>
        </Grid>
      </StackPanel>
      <Frame Source="{Binding Path=PageUri}"/>
    </DockPanel>
  </Border>
</Popup>

 Popupの上部に配置したStackPanelの中でタイトルとアイコンを表示させています。内部の配置はGridのスター単位を利用しています。

 残りの部分はFrameが占有しています。ここで、SourceプロパティにPageUriをバインドさせて、指定されたページが表示されるようにしています。

 最後に、Popupのアニメーションを作成します。

<ItemsControl.ItemTemplate>
  <DataTemplate>
    <Border BorderBrush="Black" BorderThickness="1">
      <StackPanel>
        ・・・
        <Popup Name="LeftPopup"
          PlacementTarget="{Binding ElementName=LeftTab}"
          Placement="Right" IsOpen="True">
          ・・・
          <Popup.Triggers>
            <EventTrigger RoutedEvent="Popup.MouseLeave">
              <BeginStoryboard>
                <Storyboard>
                  <DoubleAnimation
                    Storyboard.TargetName="LeftPopupBorder"
                    Storyboard.TargetProperty="Width" From="192" To="0"
                    Duration="0:0:0.5"/>
                </Storyboard>
              </BeginStoryboard>
            </EventTrigger>
          </Popup.Triggers>
        </Popup>
      </StackPanel>
      <Border.Triggers>
        <EventTrigger RoutedEvent="Border.MouseEnter">
          <BeginStoryboard>
            <Storyboard>
              <DoubleAnimation
                Storyboard.TargetName="LeftPopupBorder"
                Storyboard.TargetProperty="Width" From="0" To="192"
                Duration="0:0:0.5"/>
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="Border.MouseLeave">
          <BeginStoryboard>
            <Storyboard>
              <DoubleAnimation
                Storyboard.TargetName="LeftPopupBorder"
                Storyboard.TargetProperty="Width" From="192" To="0"
                Duration="0:0:0.5"/>
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Border.Triggers>
    </Border>
  </DataTemplate>
</ItemsControl.ItemTemplate>

 タブにマウスポインタが入った時にポップアップが現れ、タブおよびポップアップ内から外れた時に隠れていくようにします。

 以上で、左部分の表示設定が完成しました。

 右部分や下部分の表示についても、構成は左部分と同じなので省略します。詳細は「Generic.xaml」を参照してください。

最後に

 WPFを用いたカスタムコントロールの作成はどうだったでしょうか? かなりの部分をXAMLで記述でき、XAMLやWPFの強力さの一端が伺えたかと思います。

 ただ、今回の記事で解説したコントロールは必要最低限の機能しか持っていません。スプリッタを追加してサイズ変更可能にしてみたり、ドラッグ&ドロップで移動可能にしてみたりと、いくらでも改良の余地はあるでしょう。

 筆者もブログなどで継続的に情報を発信していきますので、併せて参照ください。

参考資料

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
特集記事連載記事一覧

もっと読む

この記事の著者

Piz&Yumina(ピズアンドユミナ)

平成生まれの趣味プログラマー。開発&アニメ系ブログ「かおす★ぷろじぇくと」運営中。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/2097 2008/08/26 13:11

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー