【问题标题】:Change common color in ControlTemplate更改 ControlTemplate 中的常用颜色
【发布时间】:2009-08-07 21:48:29
【问题描述】:

我有一个 ControlTemplate,它在多个元素中使用相同的颜色。在某些触发器(例如 OnMouseOver)上,我想更改该颜色。据我所知,我必须为每个元素定义一个 setter 来改变它的颜色。有没有办法引用模板中所有包含的元素都可以访问的共享资源,并且可以通过触发器进行更改,因此我不必处理每个元素?

这是一个(编造的)例子:

<ControlTemplate x:Key="myTemplate" TargetType="{x:Type Button}">
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition/>
      <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Ellipse Fill="red" Grid.Column="0"/>
    <Ellipse Fill="red" Grid.Column="1"/>
    <ContentPresenter Grid.ColumnSpan="2" VerticalAlignment="Center"/>
 </Grid>
</ControlTemplate>

当控件被禁用时,我希望省略号为灰色,无需明确设置它们,例如我不想想写

<Trigger Property="IsEnabled" Value="False">
  <Setter TargetName="_ellipse1" Property="Fill" Value="Grey"/>
  <Setter TargetName="_ellipse2" Property="Fill" Value="Grey"/>
</Trigger>

但只使用 一个 setter 设置两个椭圆的颜色。

【问题讨论】:

    标签: wpf triggers controltemplate


    【解决方案1】:

    将触发器放在省略号的样式(省略号?)而不是按钮上。如果您在 Button 上设置 IsEnabled = false,IsEnabled 将向下传播。

    <ControlTemplate x:Key="myTemplate" TargetType="{x:Type Button}">
        <ControlTemplate.Resources>
            <Style TargetType="{x:Type Ellipse}">
                <Setter Property="Fill" Value="Red" />
                <Style.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Fill" Value="Gray" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ControlTemplate.Resources>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Ellipse Grid.Column="0"/>
            <Ellipse Grid.Column="1"/>
            <ContentPresenter Grid.ColumnSpan="2" VerticalAlignment="Center"/>
        </Grid>
    </ControlTemplate>
    

    【讨论】:

    • 这以最简单的方式解决了问题,谢谢。 (虽然我必须弄清楚你不能在 ControlTemplate 中定义颜色,而只能在样式中定义。)
    • 谢谢 - 正是我需要的语法
    【解决方案2】:

    我认为最好的方法是使用价值转换器。然后你可以完全避免一个混乱的触发器。这是您的示例,但添加了转换器。

    <Window.Resources>
      <local:EnabledToColorConverter x:Key="enabledToColorConverter"/>
      <ControlTemplate x:Key="myTemplate" TargetType="{x:Type Button}">
        <Grid>
          <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
          </Grid.ColumnDefinitions>
          <Ellipse Name="_ellipse1" Fill="{TemplateBinding IsEnabled, Converter={StaticResource enabledToColorConverter}}" Grid.Column="0"/>
          <Ellipse Name="_ellipse2" Fill="{TemplateBinding IsEnabled, Converter={StaticResource enabledToColorConverter}}" Grid.Column="1"/>
          <ContentPresenter Grid.ColumnSpan="2" VerticalAlignment="Center"/>
        </Grid>
      </ControlTemplate>
    </Window.Resources>
    
    <StackPanel>
      <Button Template="{StaticResource myTemplate}">Enabled Button</Button>
      <Button Template="{StaticResource myTemplate}" IsEnabled="False">Disabled Button</Button>
    </StackPanel>
    

    这是转换器:

    public class EnabledToColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool isEnabled = (bool)value;
            return isEnabled ?
                Brushes.Red :
                Brushes.Gray;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    【讨论】:

    • 这是一个非常难看的解决方案,因为颜色在值转换器中是硬编码的(不幸的是, IValueConverter.Convert 只接受一个参数),但这可以解决问题。我会试试的。
    • 不,您可以在绑定上使用 ConverterParameter 并传递不同的颜色。或者您可以静态定义颜色并以这种方式访问​​它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多