WPFのカスタムコントロール


開発したカスタムコントロールの覚書
ちょっと凝ったカスタマイズ編

# リストビュー①
リストビューの項目を横並びにするようにしています。
項目を表示し、選択されると項目のフォントカラーを変更します。

```

<ListView x:Name="ColorView"
          ItemsSource="{Binding ColorList}"
          PreviewMouseDown="ColorView_PreviewMouseDown">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Width="1000"
                       Background="White"
                       Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <ListView.ItemContainerStyle>
        <!--  ListViewItemのスタイル  -->
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListViewItem}">
                        <Border x:Name="Bd"
                                Background="Transparent"
                                BorderBrush="Transparent"
                                BorderThickness="4"
                                Padding="0"
                                SnapsToDevicePixels="true">
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </Border>
                        <!--  ListViewItemが選択された際の状態を決定  -->
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter TargetName="Bd" Property="BorderBrush" Value="Black" />
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsSelected" Value="true" />
                                    <Condition Property="Selector.IsSelectionActive" Value="false" />
                                </MultiTrigger.Conditions>
                                <Setter TargetName="Bd" Property="Background" Value="White" />
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Visibility" Value="{Binding IsDisplay}" />
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.ItemTemplate>
        <!--  ListViewItemの中のコントロール  -->
        <ItemContainerTemplate>
            <Grid HorizontalAlignment="Left"
                  VerticalAlignment="Center"
                  Background="{Binding ColorBarRGB}">
                <!--  文字に影をつけるために軸をずらして表示する  -->
                <TextBlock Foreground="Black"
                           Style="{StaticResource ColorText}"
                           Text="{Binding ElementName=ShadeNames,
                                          Path=Text}">
                    <TextBlock.RenderTransform>
                        <!--  X,Y軸を調整  -->
                        <TranslateTransform X="3" Y="3" />
                    </TextBlock.RenderTransform>
                </TextBlock>
                <TextBlock x:Name="ShadeNames"
                           Foreground="White"
                           Style="{StaticResource ColorText}"
                           Text="{Binding FinalShadeNames}" />
            </Grid>
            <!--  Itemが選択状態の場合に文字に色を付ける  -->
            <ItemContainerTemplate.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}" Value="true">
                    <Setter TargetName="ShadeNames" Property="Foreground" Value="LightBlue" />
                </DataTrigger>
            </ItemContainerTemplate.Triggers>
        </ItemContainerTemplate>
    </ListView.ItemTemplate>
</ListView>

```
# リストビュー②
リストビューの項目を横並びにするようにしています。
また表示している四角はそれぞれ別の色を表示することができます。
バインドするデータは４色の情報を持ったobservablecollectionとして設定します

```

<ListView x:Name="ColorView"
          ItemsSource="{Binding ColorList}"
          ScrollViewer.HorizontalScrollBarVisibility="Hidden"
          ScrollViewer.VerticalScrollBarVisibility="Hidden"
          SelectionMode="Single"
          Background="Transparent"
          BorderBrush="Transparent"
          IsSynchronizedWithCurrentItem="True">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <!--  ※ 横の折り返し位置を設定する横に並べる数に合わせて調整する -->
            <WrapPanel Width="620" Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <ListView.ItemTemplate>
        <!--  ListViewItemの内容  -->
        <ItemContainerTemplate>
            <Grid Width="160"
                  Height="160"
                  Margin="18">
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <!--  それぞれのTextBlockに色をバインドする  -->
                <TextBlock Grid.Row="0"
                           Grid.Column="0"
                           Background="{Binding ColorBarRGB_part1}" />
                <TextBlock Grid.Row="0"
                           Grid.Column="1"
                           Background="{Binding ColorBarRGB_part2}" />
                <TextBlock Grid.Row="1"
                           Grid.Column="0"
                           Background="{Binding ColorBarRGB_part3}" />
                <TextBlock Grid.Row="1"
                           Grid.Column="1"
                           Background="{Binding ColorBarRGB_part4}" />
            </Grid>
        </ItemContainerTemplate>
    </ListView.ItemTemplate>
    <ListView.ItemContainerStyle>
        <!--  ListViewItemのスタイル  -->
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListViewItem}">
                        <!--  ListViewItemの外枠の定義  -->
                        <Border x:Name="Bd"
                                Background="Transparent"
                                BorderBrush="Transparent"
                                BorderThickness="2"
                                Padding="0"
                                SnapsToDevicePixels="true">
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </Border>
                        <!--  ListViewItemが選択された際の状態を決定  -->
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter TargetName="Bd" Property="BorderBrush" Value="Black" />
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsSelected" Value="true" />
                                    <Condition Property="Selector.IsSelectionActive" Value="false" />
                                </MultiTrigger.Conditions>
                                <Setter TargetName="Bd" Property="Background" Value="White" />
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>

```

# チェックボタン
msdnかどこかから持ってきたスタイル
ポイントとしては、チェックマークをベジエ曲線で描画しているのでいろいろ柔軟にカスタマイズが可能

```

<Style x:Key="SimpleLargeCheckBoxStyle" TargetType="CheckBox">
    <!--  この辺はついで  -->
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="Margin" Value="0" />
    <Setter Property="Background" Value="Transparent" />
    <!--  ここが本体  -->
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <BulletDecorator HorizontalAlignment="Center"
                                 VerticalAlignment="Center"
                                 Background="{TemplateBinding Background}">
                    <BulletDecorator.Bullet>
                        <Grid x:Name="border"
                              Width="25"
                              Height="25">
                            <Rectangle Width="13"
                                       Height="13"
                                       HorizontalAlignment="Center"
                                       VerticalAlignment="Center"
                                       Fill="Transparent"
                                       Stroke="{TemplateBinding Foreground}"
                                       StrokeThickness="2" />
                            <!--  ベジエを使えば曲線のチェックマークも描画可能  -->
                            <Path x:Name="CheckMark"
                                  Data="M 9 10 L 11 15 L 24 5"
                                  IsHitTestVisible="False"
                                  SnapsToDevicePixels="False"
                                  Stroke="{TemplateBinding Foreground}"
                                  StrokeThickness="2"
                                  Visibility="Collapsed" />
                            <Rectangle x:Name="IndeterminateMark"
                                       Width="5"
                                       Height="5"
                                       HorizontalAlignment="Center"
                                       VerticalAlignment="Center"
                                       Fill="{TemplateBinding Foreground}"
                                       IsHitTestVisible="False"
                                       Visibility="Collapsed" />
                        </Grid>
                    </BulletDecorator.Bullet>
                    <VisualStateManager.VisualStateGroups>
                        <!--  機能的に要らなさそうなアニメーションは全部廃止するスタイル  -->
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <Storyboard>
                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="border" Storyboard.TargetProperty="Opacity">
                                        <DiscreteDoubleKeyFrame KeyTime="0" Value="1" />
                                    </DoubleAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="MouseOver" />
                            <VisualState x:Name="Pressed" />
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="border" Storyboard.TargetProperty="Opacity">
                                        <DiscreteDoubleKeyFrame KeyTime="0" Value="0.6" />
                                    </DoubleAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="CheckStates">
                            <VisualState x:Name="Checked">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="IndeterminateMark" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Unchecked">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="IndeterminateMark" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Indeterminate">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="IndeterminateMark" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <BulletDecorator.Child>
                        <ContentPresenter Margin="0"
                                          HorizontalAlignment="Left"
                                          VerticalAlignment="Center"
                                          RecognizesAccessKey="True" />
                    </BulletDecorator.Child>
                </BulletDecorator>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

```