AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
25.66k stars 2.22k forks source link

Color binding on slider thumb background property in fluent theme not working properly #16592

Closed Monitor-A closed 2 months ago

Monitor-A commented 2 months ago

Describe the bug

Color binding on Slider Thumb in Fluent Theme causes it to get transparent. Color binding on other parts of the same control or different controls works fine. If I hard code the background color in axaml it also works fine.

slider_thumb_transparent

Having a look at the devtool in runtime shows the background property is of type ImmutableSolidColorBrush. I don't now if that is part of the issue but on ohter parts the type is always SolidColorBrush.

slider_devtools

To Reproduce

axaml for the slider

<Slider Grid.Column="1"
    Value="30" 
    Minimum="{Binding SliderMin}"
    Maximum="{Binding SliderMax}"
    Name="slider">

    <Slider.Styles>

        <!--left side of slider thumb-->
        <Style Selector="Slider:horizontal /template/ RepeatButton#PART_DecreaseButton">
            <Setter Property="Template">
                <ControlTemplate>
                    <Grid>
                        <Border Margin="0,-10" Background="Transparent" />
                        <Border Background="{Binding CurrentColor}"
                              CornerRadius="6,0,0,6"
                              Height="10"
                              VerticalAlignment="Center"/>
                    </Grid>
                </ControlTemplate>
            </Setter>
        </Style>

        <!--slider thumb -->
        <Style Selector="Slider:horizontal /template/ Thumb">
            <Setter Property="Width" Value="32"/>
            <Setter Property="Height" Value="32"/>
            <Setter Property="Template">
                <ControlTemplate>
                    <Border Background="{Binding CurrentColor}"
                           CornerRadius="20"/>
                </ControlTemplate>
            </Setter>
        </Style>

        <!--right side of slider thumb-->
        <Style Selector="Slider:horizontal /template/ RepeatButton#PART_IncreaseButton">
            <Setter Property="Template">
                <ControlTemplate>
                    <Grid>
                        <Border Margin="0,-10" Background="Transparent" />
                        <Border Background="White"
                              CornerRadius="0,6,6,0"
                              Height="10"
                              VerticalAlignment="Center"/>
                    </Grid>
                </ControlTemplate>
            </Setter>
        </Style>
    </Slider.Styles>
</Slider>

Expected behavior

No response

Avalonia version

11.1.1

OS

Windows

Additional context

I'm using .NET 8

timunie commented 2 months ago

What type is CurrentColor? Do you need a converter maybe? Also check DataContext of the slider.

robloo commented 2 months ago

Background requires a Brush and you are assigning a Color. Try using the ColorToBrushConverter or the ToBrushConverter in the ColorPicker nuget.

If this is the issue it's another example where Avalonia needs to be a bit smarter. WPF supports this implicitly.

Monitor-A commented 2 months ago

I’m sorry I should have made some things more clear.

The project is very simple and has only one .axaml at the frontend, no complex design patterns like MVVM are used. The DataContext comes from its corresponding .axaml.cs class.

DataContext="{Binding $self}"

The .axaml.cs class implements INotifyPropertyChanged interface and contains all properties used.

The Property CurrentColor is of type SolidColorBrush. I named this property CurrentColer because the color of the Brush changes whenever the slider is moved.

The Proeprty is used on several controls like the subtract button, add button and the RepeatButton of the slider as shown in the first picture I posted.

Wherever I bind this property like,

="{Binding CurrentColor}"

I do not encounter any problems, only the slider thumb turns transparent.

My current workaround is to iterate to all descendants of the slider, find the thumb border and set the background to CurrentColor in the ValueChanged Event of the slider.

CurrentColor = new SolidColorBrush(_colorList[(int)slider.Value - 1]);

var sliderThumbBorder = slider.GetVisualDescendants().FirstOrDefault(obj => obj.Name == "thumbBorder");

if (sliderThumbBorder != null)
    ((Border)sliderThumbBorder).Background = CurrentColor;

I have not used any converters so far, but I will do as suggested.

timunie commented 2 months ago

I don't see how the "CurrentColor" is defined. Does it have a public get? Then it should work. Is it only a field like shown above, Binding can't work.

public IBrush CurrentColor {get; } = new SolidColorBrush(_colorList[(int)slider.Value - 1]);

If you want to change it on the fly, you need to make it raise property changed.

For further notice: Attach a minimum sample for us to investigate the issue properly.

timunie commented 2 months ago

Works for me if I move the slider Style to Window.Styles instead.