Popup
Popupクラスは、ContextMenuの親のクラスで、Windowの挙動はContextMenuと同じ。たとえば、Windowの外をクリックすると受動的に閉じられます。
使い道の広いWindowです。
HTMLエディタを作るにあたって、ColorPicker と HTMLソース編集のタグ選択を作りました。
1.Popupの使い方
1.1.使用する名前空間
Popup は、System.Windows.Controls.Primitives にあります。必要になる宣言は下記です。
- using System.Windows;
- using System.Windows.Shapes;
- using System.Windows.Media;
- using System.Windows.Input;
- using System.Windows.Documents;
- using System.Windows.Controls;
- using System.Windows.Controls.Primitives;
1.2.例
Popupを継承したクラスPopup1を作ります。このインスタンスpopup1を生成し、IsOpenプロパティを true に設定すれば表示されます。
popup1の表示領域外をクリックすれば自動的に閉じられます。
- //Popup ウインドウのサンプル
- public class Popup1 : Popup
- {
- protected override void OnOpened(EventArgs e)
- {
- base.OnOpened(e);
- TextBlock tb = new TextBlock();
- tb.Text="Popupのテスト";
- tb.Background = Brushes.Magenta;
- Child = tb;
- Debug.WriteLine(Placement);
- }
- }
- Popup1 popup1 = new Popup1();
- //左ボタン押下でpopup1を開く
- private void tblock1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
- {
- //以下の挙動の設定は、Popup1クラスのOnOpened()などで行えば設定漏れを防げる
- popup1.StaysOpen = false;
- popup1.PlacementTarget = tblock1;
- popup1.Placement = PlacementMode.MousePoint;
- popup1.IsOpen = true;
- }
1.3.StayOpen
デフォルトでは、StayOpenプロパティは true であるらしく、下図のような動作になります。
このような使い方が有効な例は思いつきません。
| 1.TextBlockにPopupウインドウを表示 |
2.本体が他の窓に隠れてもPopupウインドウは最前面に残る |
 |
 |
1.4.開く位置の設定方法
下表のようです。
Placement のデフォルトは PlacementMode.Bottom のようです。
ところが、デフォルトでの表示は、モニタ画面の左上隅になります。PlacementTarget を指定しないと、作成したプログラムのウインドウとは無関係に表示されるので、表示されていないと誤解してしまいます。Bottom なのに上隅になるのは、全画面の下にPopupを付ける指定なので、折り返されていると解釈しました。
表。Popupの表示位置の設定
| Placement |
PlacementTarget |
HorizontalOffset
VerticalOffset |
表示位置 |
|
Top
Bottom
Center
Left
Right |
基準となるWindow |
- |
PlacementTargetに対して指定位置 |
| Mouse |
- |
- |
マウスポインタの位置 |
| MousePoint |
- |
マウスポインタからの相対座標 |
マウスポインタの位置に、HorizontalOffset、VerticalOffsetを加算 |
Absolute
AbsolutePoint |
- |
モニタの左上隅を原点とした絶対的な座標 |
HorizontalOffset、VerticalOffsetが示す位置 |
Relative
RelativePoint |
基準となるWindow |
PlacementTargetに対する相対座標 |
PlacementTargetに対して、HorizontalOffset、VerticalOffsetを加算 |
※AbsoluteとAbsolutePoint、RelativeとRelativePointの違いは、Popupが画面からはみ出すときの描画の仕方にあるようだが良くわからない。
2.ColorPicker の例
「文字の色」「背景色」のボタンを作って配置しました。このボタンは、文字列と色見本がキートップになっています。
ボタンがクリックされると、色見本(ColorPicker)を表示します。Placement に、PlacementMode.Buttom を、PlacementTargetにボタンを設定します。これによって、クリックしたボタンの直下に色見本が開きます。
閉じるのは、色を選択して「OK」をクリックするか、別なボタンのクリックなど領域外の事象発生で行われます。
3.タグ選択の例
HTMLをソースで編集する場合のタグ入力補助機能を作りました。HTTMLのソースを表示しているRichTextBoxと連動して動きます。
- '<'を押すと、タグ選択が開きます。
- 文字を入力するごとに、それまで入力した部分が一致するものを選択してListBoxを更新していきます。
- 入力された文字は逐次RichTextBoxに反映します。
- エンターキーかダブルクリックでListBoxの選択項目を、RichTextBoxに貼り付けます。(当然既に表示している部分を除いて)
3.1.どこに窓を開くか
通常は、マウスポインタの位置に表示されるか、きっかけになったボタンなどのコントロールの近傍に表示されるので問題を感じません。
しかし、これは、'<'キーを押したときに開くので、意味的にマウスはまったく関係ありません。
キャレットの表示位置に表示する必要があります。
- protected override void OnOpened(EventArgs e)
- {
- //標示位置をキャレットから決めて、設定する
- StaysOpen = false;
- PlacementTarget = owner;
- Placement = PlacementMode.Relative;
- Rect rect = owner.CaretPosition.GetCharacterRect(LogicalDirection.Forward);
- HorizontalOffset = rect.X;
- VerticalOffset = rect.Y + rect.Bottom;
- //本来の処理
- base.OnOpened(e);
- //ListBoxにフォーカスを設定
- lb.Focus();
- //入力文字数を初期化
- length = 0;
- }
ownerは、HTMLのソースを編集しているRichTextBoxです。
位置は相対で指定しています。
3.2.文字の入力
ここでは、フォーカスがPopupウインドウのListBoxにあります。ListBoxは項目の選択にキーボード入力を使います。
この状態で、英字キーが押されたらListBoxの項目の選択を更新します。同時に、RichTextBoxにも反映します。
Popupウインドウの OnPreviewTextInput() をオーバライドすると、ListBox で使わない文字入力だけが通るようです。
ここで、英字ならRichTextBoxへ反映しました。
一覧
| |
|
|
|
| メソッド |
|
|
|
| |
|
|
|
| |
|
|
|
| |
|
|
|
| プロパティ |
|
|
|
| HorizontalOffset |
|
|
|
| |
|
|
|
| Placement |
|
|
|
| PlacementTarget |
|
|
|
| |
|
|
|
| StaysOpen |
|
|
|
| VerticalOffset |
|
|
| |