在WPF控件上复制背景颜色

时间:2012-10-09 17:25:51

标签: wpf styles

我编写了一个用户控件,它由一个ListBox和一些额外的控件组成。我想使用与标准ListBox相同的画笔将整个事物包裹在边框中。

MSDN有一个给ListBox标准样式的页面,但它有硬编码颜色,而标准ListBox在不同平台或不同主题上使用不同样式。如何在我自己的控件中重新创建ListBox的边框?

2 个答案:

答案 0 :(得分:2)

我使用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>

您应该能够使用此默认样式中的相同画笔来获取与当前主题相关的画笔。

答案 1 :(得分:0)

我所做的是编写一个提取控件默认样式的函数,以及该样式的相关属性:

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主题的值。