WPFでLightBox風のポップアップ表示を行うサンプルを作ってみました。
コードはこちら↓
以下のような点を意識して作ってみました。
- XAML上の構造に依存しない
- ↓のBusyIndicatorのように、ポップアップ表示する要素をXAML上で最前面に定義すると、デザイナのUIが使いにくくなるため。
- https://wpftoolkit.codeplex.com/wikipage?title=BusyIndicator&referringTitle=Documentation
- 最前面にポップアップ要素があるから、XAMLデザイナ上でほかの要素クリックで選択できなくなってしまう。。。
- LightBoxでダイアログ表示する要素はXAML上には定義せず、Adornerを使って対象要素の全面に重ねて表示する
- ↓のBusyIndicatorのように、ポップアップ表示する要素をXAML上で最前面に定義すると、デザイナのUIが使いにくくなるため。
- モードレスな表示のみサポート
- 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。
こんな風に並べて表示することもできます。
もう少しいい感じにコードを整理したら、ちゃんとライブラリの形に整えてNugetにでも上げてみようかな、と。