読者です 読者をやめる 読者になる 読者になる

SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

WPFでLightBox風のポップアップ表示をするサンプル

WPF C#

WPFLightBox風のポップアップ表示を行うサンプルを作ってみました。

コードはこちら↓

以下のような点を意識して作ってみました。

  • XAML上の構造に依存しない
    • ↓のBusyIndicatorのように、ポップアップ表示する要素をXAML上で最前面に定義すると、デザイナのUIが使いにくくなるため。
    • LightBoxでダイアログ表示する要素はXAML上には定義せず、Adornerを使って対象要素の全面に重ねて表示する
  • モードレスな表示のみサポート
    • Adornerを使って同一ビジュアルツリー上に表示するんで、MessageBox.ShowみたいなノリでUIスレッドを止めると、肝心のダイアログ表示が行われない。
  • 複数ダイアログの同時表示
    • モードレス表示をするので、ダイアログ表示中に別ダイアログの表示処理が重なる可能性がある。
      • ↑みたいなときに、複数同時表示できるようにしておく。
  • 表示方法のカスタマイズ
    • Template/ItemsPanel/ItemContainerStyleなどで、表示方法をカスタマイズできるようにしておく。
    • 複数表示するときに、ItemsPanelをいじって、縦方向に並べる/横方向に並べる、というのを切り替えられる。

使い方

LightBoxの表示方法は、以下のように添付プロパティを使って色々カスタマイズできるようになってます。

MainWindow.xaml

<Window x:Class="LightBoxSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ctrl="clr-namespace:LightBoxSample.Controls"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:LightBoxSample"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="MainWindow"
        Width="525"
        Height="350"
        mc:Ignorable="d">
    <ctrl:LightBox.Template>
        <ControlTemplate>
            <Grid Background="#88000000">
                <ItemsPresenter />
            </Grid>
        </ControlTemplate>
    </ctrl:LightBox.Template>
    <ctrl:LightBox.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid/>
        </ItemsPanelTemplate>
    </ctrl:LightBox.ItemsPanel>
    <ctrl:LightBox.ItemContainerStyle>
        <Style TargetType="{x:Type ContentControl}">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Border Width="150"
                                Height="150"
                                Background="Beige"
                                BorderBrush="Black"
                                BorderThickness="2"
                                Margin="5"
                                CornerRadius="3">
                            <ContentPresenter Content="{Binding}" />
                        </Border>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ctrl:LightBox.ItemContainerStyle>
    <Window.Resources />
    <Grid>
        <Button Margin="50"
                HorizontalAlignment="Left"
                VerticalAlignment="Top"
                Click="button_Click"
                Content="Show LightBox" />
    </Grid>
</Window>

で、こんな風に表示を行います。

LightBox.Show(this, new SimpleDialog());

SimpleDialogは、ダイアログ表示の中身となるUserControl。
f:id:minami_SC:20160216075746p:plain

こんな風に並べて表示することもできます。
f:id:minami_SC:20160216075757p:plain

もう少しいい感じにコードを整理したら、ちゃんとライブラリの形に整えてNugetにでも上げてみようかな、と。