2019-01-25に投稿

【WPF】スタイルをCSSみたいに外部ファイルに定義する

読了目安:13分

今回は、C#@WPFでコンポーネントのスタイル等を外部ファイルに定義する方法を学びました。
元々、WEB系の方が経験が多いのですが、CSSっぽく出来るので分かりやすくて助かります。
早速、前回のサンプルアプリケーションを流用してやってみます。

WPFのデータグリッドでセルフォーカス時の枠線を消し去る

修正前のコード
前回のものに、検索するためのコンポーネントを配置しました。

検索用コンポーネント追加

MainWindow.xaml

<Window x:Class="WpfApp1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="一覧" Height="350" Width="530">
        <Grid>
            <Label Content="名前:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,10,0,0" />
            <TextBox x:Name="search_name" HorizontalAlignment="Left" Height="23" Margin="56,12,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120"/>
            <Label Content="種別:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="201,10,0,0" />
            <ComboBox x:Name="search_kind" HorizontalAlignment="Left" Margin="252,12,0,0" VerticalAlignment="Top" Width="120" Height="23"/>
            <Button x:Name="search_button" Content="検索" HorizontalAlignment="Left" Margin="432,12,0,0" VerticalAlignment="Top" Width="75" RenderTransformOrigin="0.467,0.792" Height="23"/>
            <DataGrid Name="dataGrid" HorizontalAlignment="Left" Height="267" Margin="10,43,0,0" VerticalAlignment="Top" Width="497" AutoGenerateColumns="False"
                      AlternationCount="1" AlternatingRowBackground="#B2CEEBF7" SelectionMode="Single" 
                      HorizontalGridLinesBrush="Gray" VerticalGridLinesBrush="Gray" >
                <DataGrid.CellStyle>
                    <Style TargetType="DataGridCell">
                        <!-- セルフォーカス時の枠線を消す -->
                        <Setter Property="BorderThickness" Value="0"/>
                        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
                        <!-- 行高さを大きくした際に、セル内容の縦配置を真ん中にする -->
                        <Setter Property="Height" Value="25"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type DataGridCell}">
                                    <Grid Background="{TemplateBinding Background}">
                                        <ContentPresenter VerticalAlignment="Center" Margin="4,4,4,4" />
                                    </Grid>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </DataGrid.CellStyle>
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding No}" ClipboardContentBinding="{x:Null}" Header="No" IsReadOnly="True" Width="50"/>
                    <DataGridTextColumn Binding="{Binding Name}" ClipboardContentBinding="{x:Null}" Header="名前" IsReadOnly="True" Width="100"/>
                    <DataGridTextColumn Binding="{Binding Sex}" ClipboardContentBinding="{x:Null}" Header="性別" IsReadOnly="True" Width="40"/>
                    <DataGridTextColumn Binding="{Binding Age}" ClipboardContentBinding="{x:Null}" Header="年齢" IsReadOnly="True" Width="40"/>
                    <DataGridTextColumn Binding="{Binding Kind}" ClipboardContentBinding="{x:Null}" Header="種別" IsReadOnly="True" Width="120"/>
                    <DataGridTextColumn Binding="{Binding Favorite}" ClipboardContentBinding="{x:Null}" Header="好物" IsReadOnly="True" Width="*"/>
                </DataGrid.Columns>
            </DataGrid>

        </Grid>
    </Window>

スタイル用外部ファイルの作成
フォルダの追加

ソリューションエクスプローラーでプロジェクトを右クリック
「追加」>「新しいフォルダ―」を選択します。

フォルダ名の変更

作成したフォルダ―を「Style」に名前変更します。

項目の追加

フォルダを右クリックし「追加」>「リソースディクショナリ」を選択します。

リソースディクショナリの追加

名前を入力し(今回は StyleDic.xaml としました)、「追加」ボタンをクリックします。
外部ファイルの記述内容
次のようにコードを記述します。

StyleDic.xaml

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

        <!-- ラベル:通常 -->
        <Style x:Key="lb-normal" TargetType="Label" >
            <Setter Property="VerticalAlignment" Value="Top" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="Foreground" Value="#FF666666" />
        </Style>

        <!-- テキスト:通常 -->
        <Style x:Key="tx-normal" TargetType="TextBox">
            <Setter Property="VerticalAlignment" Value="Top" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="Width" Value="120" />
            <Setter Property="Height" Value="25" />
            <Setter Property="TextWrapping" Value="Wrap" />
        </Style>

        <!-- コンボボックス:通常 -->
        <Style x:Key="cb-normal" TargetType="ComboBox">
            <Setter Property="VerticalAlignment" Value="Top" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="SelectedIndex" Value="0" />
            <Setter Property="Padding" Value="6,3,4,3" />
            <Setter Property="Width" Value="100" />
            <Setter Property="Height" Value="25" />
        </Style>

        <!-- ボタン:通常 -->
        <Style x:Key="btn-normal" TargetType="Button">
            <Setter Property="VerticalAlignment" Value="Top" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="Width" Value="75" />
            <Setter Property="Height" Value="25" />
        </Style>

        <!-- データグリッド:通常 -->
        <Style x:Key="grid-normal" TargetType="DataGrid">
            <Setter Property="VerticalAlignment" Value="Top" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="Grid.Row" Value="1" />
            <Setter Property="HorizontalScrollBarVisibility" Value="Visible" />
            <Setter Property="AutoGenerateColumns" Value="False" />
            <Setter Property="IsReadOnly" Value="True" />
            <Setter Property="AlternationCount" Value="1" />
            <Setter Property="AlternatingRowBackground" Value="#B2CEEBF7" />
            <Setter Property="SelectionMode" Value="Single" />
        </Style>
        <Style TargetType="DataGridCell">
            <Setter Property="BorderThickness" Value="0" />
            <Setter Property="FocusVisualStyle" Value="{x:Null}" />
            <Setter Property="Height" Value="25" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type DataGridCell}">
                        <Grid Background="{TemplateBinding Background}">
                            <ContentPresenter VerticalAlignment="Center" Margin="4,4,4,4" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </ResourceDictionary>

修正後のソース
次のように修正します。

MainWindow.xaml

<Window x:Class="WpfApp1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="一覧" Height="350" Width="530">
        <Window.Resources>
            <ResourceDictionary Source="/Style/StyleDic.xaml"/>
        </Window.Resources>
        <Grid>
            <Label Content="名前:" Margin="10,10,0,0" Style="{StaticResource lb-normal}"/>
            <TextBox x:Name="search_name" Margin="56,12,0,0" Style="{StaticResource tx-normal}"/>
            <Label Content="種別:" Margin="201,10,0,0" Style="{StaticResource lb-normal}"/>
            <ComboBox x:Name="search_kind" Margin="252,12,0,0" Style="{StaticResource cb-normal}"/>
            <Button x:Name="search_button" Content="検索" Margin="432,12,0,0" Style="{StaticResource btn-normal}"/>
            <DataGrid Name="dataGrid" HorizontalAlignment="Left" Margin="10,43,0,0" Width="497" Height="267" Style="{StaticResource grid-normal}">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding No}" ClipboardContentBinding="{x:Null}" Header="No" IsReadOnly="True" Width="50"/>
                    <DataGridTextColumn Binding="{Binding Name}" ClipboardContentBinding="{x:Null}" Header="名前" IsReadOnly="True" Width="100"/>
                    <DataGridTextColumn Binding="{Binding Sex}" ClipboardContentBinding="{x:Null}" Header="性別" IsReadOnly="True" Width="40"/>
                    <DataGridTextColumn Binding="{Binding Age}" ClipboardContentBinding="{x:Null}" Header="年齢" IsReadOnly="True" Width="40"/>
                    <DataGridTextColumn Binding="{Binding Kind}" ClipboardContentBinding="{x:Null}" Header="種別" IsReadOnly="True" Width="120"/>
                    <DataGridTextColumn Binding="{Binding Favorite}" ClipboardContentBinding="{x:Null}" Header="好物" IsReadOnly="True" Width="*"/>
                </DataGrid.Columns>
            </DataGrid>

        </Grid>
    </Window>

外部ファイルの読み込み部分

        <Window.Resources>
            <ResourceDictionary Source="/Style/StyleDic.xaml"/>
        </Window.Resources>

スタイルの適用部分

Style="{StaticResource [x:Key]}"

 

と、こんな感じですかね。

修正後画面

コードもすっきりしたし、
スタイルもちゃんと反映されていますね。

(今回はあくまでスタイルの外部ファイル化のため、検索できるようにはしていません。)

次回(時期未定)はその他のリソースについても
外部ファイルで定義してみるって感じでやりたいなと思います。

ではでは。

 

Originally published at www.doraxdora.com
ツイッターでシェア
みんなに共有、忘れないようにメモ

doraxdora

IT関係の仕事をしています/1985年生まれの東京在住/便利なサービスやツール漁りや料理などが好き/2017年~ブログやってます/自分でサービスとか作ってリリースしたい/何かありましたらお気軽にDMどうぞ

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント