見切り発車

とりあえずかきとめたい

ItemsControl でリストの内容を表示する

独自スクリプトのエディタを作ろうと思ってます。スクリプトはだいたいこんな感じ。

コマンド1 パラメータ1,パラメータ2,パラメータ3
コマンド2 パラメータ1,パラメータ2,パラメータ3,パラメータ4
コマンド3 ...

パラメータの部分のUI はこんな見た目。パラメータの値の部分はクリックするとテキストボックスになります。

f:id:uyamae:20170617013027p:plain

このデザインにしたいのは個人的な趣味の割合が大きいです。普段はラベル、編集時だけテキストボックスにするのは前回の
クリックしたら編集できるようになるラベルがつくれた - 見切り発車でやった方法です。

パラメータは複数あってリストになってます。これを横に並べて表示するにはItemControls を使用します。

<StackPanel>
    <!-- パラメータリストを表示するItemsControl -->
    <ItemsControl Template="{StaticResource ParamList}"
                  ItemTemplate="{StaticResource Param}">
        <local:ScriptParameter ParamName="パラメータ1" Value="にゃー" />
        <local:ScriptParameter ParamName="パラメータ2" Value="にゃにゃー" />
        <local:ScriptParameter ParamName="パラメータ3" Value="にゃにゃにゃー" />
    </ItemsControl>
</StackPanel>

アイテムを横に並べて表示するためにItemsControl にTemplate を指定してます。ItemTemplate は各パラメータ用の表示用です。

<!-- パラメータリストを水平に並べる -->
<ControlTemplate x:Key="ParamList">
    <StackPanel Orientation="Horizontal" IsItemsHost="True"></StackPanel>
</ControlTemplate>
<!-- パラメータリストの各項目 -->
<DataTemplate x:Key="Param" DataType="local:ScriptParameter">
    <StackPanel Orientation="Horizontal" Margin="3,2">
        <TextBlock Text="{Binding ParamName}" />
        <TextBlock Text=":" Margin="2,0" />
        <TextBox Text="{Binding Value}">
            <TextBox.Style>
                <Style TargetType="TextBox">
                    <Style.Triggers>
                        <!-- 普段はラベルに偽装する -->
                        <Trigger Property="IsFocused" Value="False">
                            <Setter Property="BorderThickness" Value="0" />
                            <Setter Property="Cursor" Value="Arrow" />
                            <!-- ただのラベルではないことを示すためハイパーリンク風に
                                 青字+アンダーラインで装飾する -->
                            <Setter Property="TextDecorations" Value="Underline" />
                            <Setter Property="Foreground" Value="Blue" />
                        </Trigger>
                        <!-- マウスオーバー時に太字にする -->
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsFocused" Value="False" />
                                <Condition Property="IsMouseOver" Value="True" />
                            </MultiTrigger.Conditions>
                            <Setter Property="FontWeight" Value="Bold" />
                        </MultiTrigger>
                    </Style.Triggers>
                </Style>
            </TextBox.Style>
        </TextBox>
    </StackPanel>
</DataTemplate>

ネストが深いのが気になりますがやりたいことはできてるのでとりあえずOK。