Search code examples
c#windows-store-appsinotifypropertychanged

Button binding on background color does not update before pointer leaves button


I have created a button in code behind like this:

btnToggleOpen = new Button();

The button is placed inside a custom UserControl that has a IsCollapsed property. The UserControl implements the INotifyPropertyChanged interface and invokes a PropertyChangedEvent when set.

I have created a binding for the background color of the button (the source contentp is the custom UserControl):

Binding backgroundBinding = new Binding();
backgroundBinding.Source = contentp;
backgroundBinding.Path = new PropertyPath("IsCollapsed");
backgroundBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
backgroundBinding.Converter = new CollapsedSettingsPanelBackgroundValueConverter();

BindingOperations.SetBinding(contentp.BtnToggleOpen, Button.BackgroundProperty, backgroundBinding);

When I click the button the IsCollapsed is toggled by IsCollapsed = !IsCollapsed;. The background color does change, but not before I move the pointer away from the button. When the pointer is over the button it seems like the background color of the button becomes transparent.

Why does the button become transparent when the pointer is over and how can I override this when the button is created in C#?


Solution

  • Take a look at the default template for a button at Button Styles and Templates or by selecting your button in the designer, right clicking, and choosing Edit Template.Edit a copy...

    In the VisualState for PointerOver you'll see that the default template animates the foreground and background values to ButtonPointerOver...ThemeBrushes, overriding the Background property that you set:

    <VisualState x:Name="PointerOver">
        <Storyboard>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Border">
                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPointerOverBackgroundThemeBrush}"/>
            </ObjectAnimationUsingKeyFrames>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPointerOverForegroundThemeBrush}"/>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
    

    When you move the pointer off of the button it transitions back to the Default state and reverts to the set value.

    You can override this by editing the copy created with the Edit Template.Edit a copy... menu. You probably still want the button to change to indicate pointer over, but you likely want it to change to something related to your new colour similar to how the default Background is Transparent and the default ButtonPointerOverBackgroundThemeBrush is mostly transparent but with a slight black or white tint depending on if it's light or dark themed.