我编写了一个用户控件,它由一个 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 主题的值。