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

Firefox の検索バーもどきを作る(1)

はじめに

WPF でなら Firefox の検索バーみたいなコントロールが簡単に作れるのではないかと思い挑戦してみました。

今回作成したサンプルの実行画面

Window に貼り付けて実行したのがこちら。
f:id:griefworker:20090407151507p:image
結構いい感じ。

プロジェクトを作成

  1. 新規に WPF アプリケーションプロジェクト作成
  2. プロジェクトに WPF カスタムコントロールを追加(コントロール名は「SearchBar」)

Generic.xaml を編集

Themes フォルダに追加された Generic.xaml に検索バーのスタイルを記述します。

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SearchBarSample">

    <!--コントロールの枠線-->
    <LinearGradientBrush x:Key="GeneralBorderBrush" EndPoint="0,20" StartPoint="0,0">
        <GradientStop Color="#FFABADB3" Offset="0.05"/>
        <GradientStop Color="#FFE2E3EA" Offset="0.07"/>
        <GradientStop Color="#FFE3E9EF" Offset="1"/>
    </LinearGradientBrush>
    
    <!--検索エンジン選択ボタンの背景を塗り潰すブラシ-->
    <LinearGradientBrush x:Key="SearchEngineButtonBrush" StartPoint="0,0" EndPoint="1,2">
        <LinearGradientBrush.GradientStops>
            <GradientStop Color="{x:Static SystemColors.ControlLightColor}" Offset="0"/>
            <GradientStop Color="{x:Static SystemColors.ControlColor}" Offset=".2"/>
        </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
        
    <!--検索エンジン選択ボタンのスタイル-->
    <Style x:Key="SearchEngineButtonStyle" TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <!--枠線は右辺だけ引く-->
                    <Border x:Name="SearchEngineButtonBorder"
                            BorderBrush="{StaticResource GeneralBorderBrush}"
                            BorderThickness="0,0,1,0"
                            Background="{StaticResource SearchEngineButtonBrush}"
                            Padding="2">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <ContentPresenter Grid.Column="0"/>
                            <!--▼を描画する-->
                            <Path Grid.Column="1" Width="8" Height="4" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stretch="Uniform" Margin="0,0,0,0" Data="F1 M 531.107,321.943L 541.537,321.943L 536.322,328.042L 531.107,321.943 Z ">
                                <Path.Fill>
                                    <SolidColorBrush Color="#FF333333"/>
                                </Path.Fill>
                            </Path>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <!--検索実行ボタンのスタイル-->
    <Style x:Key="SearchButtonStyle" TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <!--Content だけを表示する-->
                    <!--枠線や背景色は無し-->
                    <ContentPresenter/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <!--検索バーコントロールのスタイル-->
    <Style TargetType="{x:Type local:SearchBar}">
        <Setter Property="BorderBrush" Value="{StaticResource GeneralBorderBrush}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:SearchBar}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Button x:Name="SelectEngineButtonPart"
                                    IsTabStop="False"
                                    Focusable="False"
                                    Style="{StaticResource SearchEngineButtonStyle}"
                                    Grid.Column="0"
                                    Grid.Row="0">
                                <Image Source="\Images\Default.ico" Grid.Column="0" Stretch="Uniform"/>
                            </Button>
                            <TextBox x:Name="TextBoxPart"
                                     Background="{TemplateBinding Background}"
                                     BorderThickness="0"
                                     VerticalContentAlignment="Center"
                                     Grid.Column="1"
                                     Grid.Row="0">
                            </TextBox>
                            <Button x:Name="SearchButtonPart"
                                    Width="32"
                                    IsTabStop="False"
                                    Focusable="False"
                                    Style="{StaticResource SearchButtonStyle}"
                                    Command="{x:Static local:SearchBar.SearchCommand}"
                                    Grid.Column="2"
                                    Grid.Row="0">
                                <Image Source="\Images\Search.ico" Stretch="None" />
                            </Button>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

枠線やボタンの背景色はそれっぽいものにしています。
検索実行ボタンはアイコンだけを表示し、背景色や枠線は描画しません。マウスオーバー時やクリック時に色が変わることもありません。Firefox と同じです。
そうそう、もちろん ExpressionBlend は使っていません。漢なので XAML は直書きです。

今回はこれまで

今回は検索バーの外観を作成しました。次回は中身を実装します。