1
votes

I have a series of ToggleButtons that have a style applied to them. I want to be able to change the background colour when a button is checked. Each ToggleButton is assigned to the same Checked event which has the following code.

Private Sub togAnswer_Checked(ByVal sender as Object, ByVal e as System.Windows.RoutedEventArgs)
    'togAnswer was clicked....
    Dim togC as ToggleButton
    Dim togS as String = TryCast(sender, ToggleButton).Name.ToString()
    'Cycle through all answers and set style
    Dim bc = New BrushConverter()

    For x = 1 to 3
        togC = DirectCast(FindName("togAnswer" & x), ToggleButton) 

        If togS = "togAnswer" & x.ToString Then
            'Set ToggleButton to selected colour
            togC.Background = DirectCast(bc.ConvertFrom("#AAFF8020"), Brush)
        Else    
            'Set other ToggleButtons to unselected colour
            togC.Background = DirectCast(bc.ConvertFrom("#AA000000"), Brush)
        End If
    Next
End Sub

The code correctly identifies the source ToggleButton but does not change the color.

The style assigned to the ToggleButtons is:

<Style x:Key="GlassToggleButton" TargetType="{x:Type ToggleButton}">
    <Setter Property="FontSize" Value="24" />
    <Setter Property="Foreground" Value="White" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Border x:Name="ToggleBorder" 
                    CornerRadius="0 15 0 15" 
                    Background="#AA000000"  
                    BorderBrush="#99FFFFFF"
                    RenderTransformOrigin="0.5,0.5">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="1.7*"/>
                        </Grid.RowDefinitions>
                        <Border Grid.Row="0" CornerRadius="0,14,0,0">
                            <Border.Background>
                                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                                    <GradientStop Color="#02FFFFFF" Offset="0"/>
                                    <GradientStop Color="#55FFFFFF" Offset="0.5"/>
                                    <GradientStop Color="#11FFFFFF" Offset="1"/>
                                </LinearGradientBrush>
                            </Border.Background>
                        </Border>
                        <ContentPresenter x:Name="ToggleContentPresenter"
                            VerticalAlignment="Center"
                            HorizontalAlignment="Center"
                            Grid.RowSpan="2" />
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="RenderTransform" TargetName="ToggleBorder">
                            <Setter.Value>
                                <TransformGroup>
                                    <ScaleTransform ScaleX="0.95" ScaleY="0.95"/>
                                </TransformGroup>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Background" Value="#AAFF8020" />
                    </Trigger>
                    <Trigger Property="IsChecked" Value="True">
                        <Setter Property="Background" Value="#AAFF8020" />
                    </Trigger>
                    <Trigger Property="IsChecked" Value="False">
                        <Setter Property="Background" Value="#AA000000" />
                    </Trigger>
                    <Trigger Property="IsChecked" Value="{x:Null}">
                        <Setter Property="Background" Value="#AA000000" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
1
Is there any reason you can't do this in the Xaml? That's a lot easier and more robust.Dan Puzey
I'm new to wpf... I tend to develop .net web apps. The app I'm building is a quiz app where there could be up to 3 possible answers/question. So as I display each question the appropriate number of buttons are made visible. As a user clicks the button its background changes colour. If the user changes their mind then the previous selected button must be unchecked and it background colour reverted and the new selection checked. There is also a option to go back through questions and so I need to check the answer that was selected which the user can change if they want. Open to advice.Mych
Well, it's a matter of about 5 lines of Xaml in your style to change the background colour when a ToggleButton is checked.Dan Puzey
Ok... I look this up... So all I will need to do is control what is checked and what is not in codebehind... is that right?Mych
@Dan Actually checked my style and there is a IsPressed and IsChecked Trigger. Only the IsPressed seems to work.Mych

1 Answers

2
votes

Because you're setting background colours of the border explicitly in your template, a trigger that overrides Background will not work (your template will ignore it). What you need to do is refactor your style to respect the control's own Background.

Instead of setting Background="#AA000000" on your Border, set Background="{TemplateBinding Background}" - this kind of binding only works within a ControlTemplate. Then, add another setter in your style that sets Background to #AA000000. You should then find that your triggers have an effect!