Home > Software design >  Control button foreground color with ControlTemplate.Triggers
Control button foreground color with ControlTemplate.Triggers

Time:09-17

I have a button class that is meant to expand the style control through a template, largely taken from this question. In addition to the subject matter of the post, I also want to control the color of a disabled button through the template, rather than having to manually change it on the state-change of the button. One answer on the post by Sebastian Ax seems to indicate how this is possible, <Setter Property="TextElement.Foreground" TargetName="Content" Value="FFA0A0A0"/> as seen in my code example below, but this throws an error whenever included. Only by removing this line entirely will it run. When included, I get one of three errors (included after my main code). Which one I get seems pretty inconsistent except for possibly relating to whether I build all projects or current project in the solution, but even then I could easily get one after another on multiple attempted launches of the window.

Code:

<Button x:Class="Resources.ButtonExt"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    mc:Ignorable="d" 
    d:DesignHeight="450" d:DesignWidth="800"
    x:Name="buttonExtension">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="BorderBrush" Value="#FFA0A0A0"/>
            <Setter Property="Foreground" Value="{Binding Foreground}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border x:Name="Border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
                            <ContentPresenter Name="Content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="#FFE5F1FB" TargetName="Border"/>
                                <Setter Property="BorderBrush" Value="#FF0078D6" TargetName="Border"/>
                            </Trigger>
                            <Trigger Property="IsFocused" Value="True">
                                <Setter Property="BorderBrush" Value="#FF0078D6" TargetName="Border"/>
                                <Setter Property="BorderThickness" Value="2" TargetName="Border"/>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Background" Value="#FFCCE4F7" TargetName="Border"/>
                                <Setter Property="BorderBrush" Value="#FF005499" TargetName="Border"/>
                                <Setter Property="BorderThickness" Value="1" TargetName="Border"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="Background" Value="#FFB3B3B3" TargetName="Border"/>
                                <Setter Property="BorderBrush" Value="#FFA0A0A0" TargetName="Border"/>
                                <!-- This is the line in question, whose inclusion seems to break my GUI -->
                                <Setter Property="TextElement.Foreground" Value="FFA0A0A0" TargetName="Content"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Button.Style>
</Button>

Errors:

The fun part here is that, for some reason, when I go to change the button class file, it starts causing another unrelated component to register errors. My user control does not contain any buttons, and buttons are only added to the main window, contained within a StackPanel within a grid that also contains my user control. The third error below seems to indicate there's an issue with the line of code noted above, but I can't tell what the issue might be.

  • System.Windows.Markup.XamlParseException: 'The invocation of the constructor on type 'Resources.z_ListBoxUserControl that matches the specified binding constraints threw an exception.' Line number '53' and line position '4'. ---> System.Exception: The component 'Resoruces.z_ListBoxUserControl' does not have a resource identified by the URI '/Resources;component/z_listboxusercontrol.xaml'.
  • System.Windows.Markup.XamlParseException: 'Set connectionId threw an exception.' Line number '53' and line position '4'. ---> System.InvalidCastException: [A]Namespace.z_ListBoxUserControl cannot be cast to [B]Resources.z_ListBoxUserControl. Type A originates from 'Resources,Version=1.0.7914.17476, Culture=neutral, PublicKeyToken=null' in the context 'LoadNeither' in a byte array. Type B originates from 'Namespace, Version=1.0.7914.17476, Culture=neutral, PublicKeyToken=null' in he context 'LoadNeither' in a bypte array.
  • System.Windows.Markup.XamlParseException: 'Provide value on 'System.Windows.Baml2006.DeferredBinaryDeserializerExtension' threw an exception.' Line number '44' and line position '66'. ---> System.FormatException: Token is not valid.

So, what am I doing wrong here? Is there another way that I can reliably change the foreground color of the button? I'm aware there's difficulty with setting it, and that's why I can't just set it using Property="Foreground". I've tried using the following snippet as well, but had difficulty working out how to assign the foreground color value from the Template.Triggers. If this is the route I should go, I'd appreciate help working it out, as well.

<ControlTemplate.Resources>
    <Style TargetType="TextBlock" x:Key="ButtonLabel">
        <Setter Property="Text" Value="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"/>
        <Setter Property="Foreground" Value="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"/>
    </Style>
</ControlTemplate.Resources>

Edit:

I should note, I have also attempted putting a textblock inside the button, and this also throws the same errors.

Also, I am not building this in the VS environment, but in an IDE that comes with another software that allows for the building of macros for this software. I am aware this may cause issues, but so far I've been able to work everything else out and get it working fine.

CodePudding user response:

I think your problem comes from Value="FFA0A0A0". you should write Value="#FFA0A0A0".

  • Related