かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

WPF4.5入門 その40 「Popup、ToolTip、TextBox、Image、MediaElementコントロール」

全然関連性のないコントロールをまとめた記念すべき40回です。

Popupコントロール

opupコントロールは、画面上に別ウィンドウとして項目を表示するためのコントロールです。Popupコントロールは、IsOpenプロパティを持っていて、このプロパティの値がtrueになったときに表示されます。Popupコントロールは、デフォルトでは、親要素の下に表示されます。PlacementプロパティにTop、Bottom、Right、Leftなどの値を設定することで表示位置を下以外にすることが出来ます。

Buttonコントロールの周りにPopupコントロールが表示されるプログラムの例を以下に示します。

<Grid>
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button Content="popup button" Click="Button_Click"/>
        <Popup x:Name="popup1">
            <TextBlock Background="LightGray" Text="Bottom(Default)" />
        </Popup>
        <Popup x:Name="popup2" Placement="Left">
            <TextBlock Background="LightGray" Text="Left" />
        </Popup>
        <Popup x:Name="popup3" Placement="Top">
            <TextBlock Background="LightGray" Text="Top" />
        </Popup>
        <Popup x:Name="popup4" Placement="Right">
            <TextBlock Background="LightGray" Text="Right" />
        </Popup>
    </StackPanel>
</Grid>

Buttonを押すたびに表示、非表示を切り替えています。

private void Button_Click(object sender, RoutedEventArgs e)
{
    var popups = new[] 
    {
        this.popup1,
        this.popup2,
        this.popup3,
        this.popup4
    };

    foreach (var popup in popups)
    {
        popup.IsOpen = !popup.IsOpen;
    }
}

実行してButtonをクリックすると以下のように上下左右にPopupコントロールが表示されます。

f:id:okazuki:20140816220423p:plain

Popupコントロールは非常に低レベルなレイヤのコントロールで、柔軟に細かく設定ができる反面制御がとても難しいコントロールになります。普通は、ComboBoxコントロールやContextMenuコントロールなどで内部的にPopupコントロールが使われているので、そちらを使いますが、どうしてもPopupさせるWindowがほしい場合は、このコントロールの利用を検討してください。(例としてはインテリセンスの自前実装など)

Popupコントロールの細かい制御方法についてはMSDNの以下のページを参照してください。

ToolTipコントロール

ToolTipコントロールは、マウスをコントロール上に置いたときに補助的な情報を表示するためのコントロールです。ToolTipをコントロールに表示するには、ほぼ全てのコントロールの基底クラスであるFrameworkElementクラスとFrameworkContentElementクラスで定義されているToolTipプロパティを使用します。

一番単純な例は、ToolTipプロパティに文字列を指定する方法です。

<Button Content="Button" ToolTip="ツールチップ" />

このボタンの上にマウスカーソルを持っていくと、以下のようにツールチップが表示されます。

f:id:okazuki:20140816220700p:plain

ToolTipコントロールは、Buttonコントロールなどと同じContentControlを親に持ちます。そのため、ToolTipコントロールのContentプロパティにコントロールを直接入れて表示したり、ContentTemplateプロパティを使ってデータを任意の形で表示することが出来ます。

以下は、ToolTip内に画像を表示している例です。

<Button Content="Button">
    <Button.ToolTip>
        <ToolTip>
            <StackPanel Orientation="Horizontal">
                <Image Source="anthem.jpg" Height="100" />
                <TextBlock Text="アンセム" />
            </StackPanel>
        </ToolTip>
    </Button.ToolTip>
</Button>

実行して、ボタンの上にマウスカーソルを持っていくと以下のように表示されます。

f:id:okazuki:20140816220750p:plain

TextBoxコントロール

TextBoxコントロールは文字列を入力するインターフェースを提供するコントロールです。入力された文字列は、Textプロパティで取得できます。Textが変更されたタイミングはTextChangedイベントを購読することで判別できます。

基本的なTextBoxの使用方法を以下に示します。

<StackPanel>
    <TextBox TextChanged="TextBox_TextChanged" />
    <TextBlock x:Name="textBlock" TextWrapping="Wrap"/>
</StackPanel>
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    var textBox = (TextBox)sender;
    this.textBlock.Text = textBox.Text + "が入力されました";
}

TextBoxコントロールの入力内容をTextBlockコントロールへ設定しています。実行すると以下のようになります。

f:id:okazuki:20140816220851p:plain

改行やタブを受け入れるTextBoxコントロール

TextBoxコントロールは、デフォルトでは、改行やタブを受け付けません。メモ帳のような動作をさせるためには、以下の4つのプロパティを使用します。

プロパティ 説明
public bool AcceptsReturn { get; set; } Enterキーを押すことで改行をすることができるかどうかを取得または設定します。デフォルト値はfalse(改行できない)です。
public bool AcceptsTab { get; set; } Tabキーを押すことでタブを挿入するかどうかを取得または設定します。デフォルト値はfalse(タブではなくフォーカス移動をする)です。
public Visibility HorizontalScrollBarVisibility { get; set; } 水平方向のスクロールバーの表示方法を指定します。以下の値が設定可能です。Auto:必要な場合は表示をして不要な場合は非表示になります。Disable:無効化します。Visible:常に表示します。Hidden:非表示にします。
public Visibility VerticalScrollBarVisibility { get; set; } 垂直方向のスクロールバーの表示方法を指定します。設定値はHorizontalScrollBarVisibilityと同じです。

改行や、タブの挿入が可能で、横スクロールバーと縦スクロールバーが常に表示されるTextBoxコントロールは以下のように定義します。

<TextBox 
    AcceptsReturn="True"
    AcceptsTab="True"
    HorizontalScrollBarVisibility="Visible"
    VerticalScrollBarVisibility="Visible"/>

実行して文字を打ち込むと以下のように改行や、スクロールバーの表示を確認できます。

f:id:okazuki:20140816221110p:plain

Imageコントロール

Imageコントロールは、画面に画像を表示するコントロールです。Sourceプロパティに指定した画像と、Stretchプロパティに指定した画像の拡大方法をもとに、画像を表示します。StretchプロパティはViewBoxの拡大方法と同じ方法で画像を拡大・縮小します。

SourceプロパティはImageSource型ですが、XAMLからは文字列で画像のURIを指定することが出来ます。プロジェクトにビルドアクションResourceに指定された画像はプロジェクトのルートからの相対URIで指定可能です。プロジェクトにanthem.jpgという画像がある場合に、それを表示するImageコントロールのXAMLは以下のようになります。

<Image Source="anthem.jpg" Stretch="UniformToFill" />

実行すると以下のように表示されます。

f:id:okazuki:20140816221157p:plain

コードからSourceプロパティを指定するコードを以下に示します。画面のXAMLは以下の通りです。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Menu>
        <MenuItem Header="開く(_O)" Click="MenuItem_Click" />
    </Menu>
    <Image x:Name="image" Grid.Row="1" Stretch="Uniform" />
</Grid>

メニューで画像を開いて、Imageに表示するというUIです。MenuItemのクリック時の処理は以下のようになります。処理内容はコメントの通りです。

private void MenuItem_Click(object sender, RoutedEventArgs e)
{
    // 画像を開く
    var dialog = new OpenFileDialog();
    dialog.Filter = "画像|*.jpg;*.jpeg;*.png;*.bmp";
    if (dialog.ShowDialog() != true)
    {
        return;
    }

    // ファイルをメモリにコピー
    var ms = new MemoryStream();
    using (var s = new FileStream(dialog.FileName, FileMode.Open))
    {
        s.CopyTo(ms);
    }
    // ストリームの位置をリセット
    ms.Seek(0, SeekOrigin.Begin);
    // ストリームをもとにBitmapImageを作成
    var bmp = new BitmapImage();
    bmp.BeginInit();
    bmp.StreamSource = ms;
    bmp.EndInit();
    // BitmapImageをSourceに指定して画面に表示する
    this.image.Source = bmp;
}

実行してファイルを開くと以下のように画面に画像が表示されます。

f:id:okazuki:20140816221307p:plain

MediaElementコントロール

MediaElementコントロールは、音楽や動画を再生するためのコントロールになります。Sourceプロパティに再生したいファイルへのURIを指定して使用します。LoadedBehaviorプロパティをManualにすることで、Playメソッドで再生を行い、Pauseメソッドで一時停止を行い、Stopメソッドで停止を行うなどの細かい制御が可能になります。またVolumeプロパティやSpeedRatioプロパティによって一般的な動画プレイヤーが備えるべき基本機能を提供します。

ファイルを開いて再生するコードを以下に示します。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Menu>
        <MenuItem Header="開く(_O)" Click="MenuItem_Click" />
    </Menu>
    <MediaElement x:Name="mediaElement" Grid.Row="1" />
</Grid>
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
    // 動画を開く
    var dialog = new OpenFileDialog();
    dialog.Filter = "動画|*.mp4";
    if (dialog.ShowDialog() != true)
    {
        return;
    }

    // SourceにURIを指定して再生する。
    // LoadedBehaviorがPlay(デフォルト値)なので自動再生される。
    var uri = new Uri(dialog.FileName);
    this.mediaElement.Source = uri;
}

実行して動画を開いた画面を以下に示します。

f:id:okazuki:20140816221442p:plain

過去記事