ListBox といくつかの追加コントロールで構成されるユーザー コントロールを作成しました。標準の ListBox と同じブラシを使用して、全体を境界線でラップしたいと考えています。
MSDNには ListBox の標準スタイルが指定されたページがありますが、標準の ListBox は異なるプラットフォームまたは異なるテーマで異なるスタイルを使用するのに対し、色はハードコーディングされています。自分のコントロールで ListBox の境界線を再作成するにはどうすればよいですか?
Microsoft Expression Blend を使用して、標準の ListBox テンプレートのコピーを作成しました。これが私がそこから得たものです...
<SolidColorBrush x:Key="ListBorder" Color="#828790"/>
<Style x:Key="ListBoxStyle2" TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource ListBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="1" SnapsToDevicePixels="true">
<ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
このデフォルト スタイルで同じブラシを使用して、現在のテーマに関連するブラシを取得できるはずです。
私が行ったことは、コントロールのデフォルトスタイルと、そのスタイルから関連するプロパティを抽出する関数を作成することです。
private static TReturn ExtractStyleProperty<TReturn, TFromControl>(string name, TReturn defVal)
{
var style = Application.Current.FindResource(typeof(TFromControl)) as Style;
if (style == null){
return defVal;
}
var setter = style.Setters.Where(s => s is Setter).Cast<Setter>().First(s => s.Property.Name.Equals(name));
if (setter == null){
return defVal;
}
return (TReturn)setter.Value;
}
これで、再作成するプロパティごとにプロパティを作成できます。
public Brush ListBoxBorderBrush {
get {
return ExtractStyleProperty<Brush, ListBox>("BorderBrush", new SolidColorBrush(Color.FromRgb(130, 135, 144)));
}
}
次に、コントロールのプロパティをそれらのプロパティにバインドします。これにより、システムとWPFテーマに適した値が取得されます。