Search code examples
c#.netxamlavalonia

Avalonia Radiobutton Style


I have this code in my Window.Resources

<Style Selector="RadioButton.Nav" >
        <Setter Property="FontSize" Value="6"/>
        <Setter Property="FontWeight" Value="Bold"/>            
        <Setter Property="BorderBrush" Value="Black"/>
        <Setter Property="Margin" Value="5 5 5 0"/>
        <Setter Property="Template" >
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RadioButton}">
                    <ControlTemplate.Content>
                        <Border
                        Height="{TemplateBinding Height}"
                        CornerRadius="12"
                        Width="180"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}">
                            <ContentPresenter
                                VerticalAlignment="Center"
                                HorizontalAlignment="Center"/>
                        </Border>
                    </ControlTemplate.Content>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

And then, I used it on my radiobutton

<RadioButton Classes="Nav" Content="Dashboard"/>

Im trying to change the design of my radiobutton to make it look like a button, but when I use the style, the radiobutton disappers. The code works in WPF, but I can't make it work in Avalonia.


Solution

  • First off, Styles go in Window.Styles, not Window.Resources.

    Second, you don't need to specify the TargetType in Avalonia. Remove TargetType="{x:Type RadioButton}" (I'm unsure if this would cause a problem, but I know it's not needed).

    Finally, your provided ContentPresenter is overwriting important bindings for Content and ContentTemplate, I recommend in your case to just copy the one from the Fluent theme since all you are changing is alignment and you can set that by setting the HorizontalContentAlignment and VerticalContentAlignment properties in the style itself.

    One last note, consider TemplateBinding the CornerRadius and Width as well, this make further styling easier down the road. Unlike WPF, CornerRadius does not need to be an attached property (i.e. use CornerRadius not Border.CornerRadius)

    One last and final note, controls in Avalonia have a different default for VerticalAlignment and HorizontalAlignment. This caused me quite a bit of confusion when I started. It works exactly the same as WPF but in WPF the Default is "Stretch" where as in Avalonia it is "Left" and "Center" respectively, so the style below will be left and vertically centered and 180 wide on the window, it will not fill the container vertically and be horizontally centered like WPF, if you want that set VerticalAlignment to Stretch and HorizontalAlignment to Stretch or Center.

    <Window.Styles>
        <Style Selector="RadioButton.Nav" >
          <Setter Property="FontSize" Value="6"/>
          <Setter Property="FontWeight" Value="Bold"/>
          <Setter Property="BorderBrush" Value="Black"/>
          <Setter Property="BorderThickness" Value="1"/>
          <Setter Property="Margin" Value="5 5 5 0"/>
          <Setter Property="HorizontalContentAlignment" Value="Center"/>
          <Setter Property="VerticalContentAlignment" Value="Center"/>
          <Setter Property="CornerRadius" Value="12"/>
          <Setter Property="Width" Value="180"/>
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate>
                <Border
                  Height="{TemplateBinding Height}"
                  CornerRadius="{TemplateBinding CornerRadius}"
                  Width="{TemplateBinding Width}"
                  BorderThickness="{TemplateBinding BorderThickness}"
                  Background="{TemplateBinding Background}"
                  BorderBrush="{TemplateBinding BorderBrush}">
                  <ContentPresenter
                    Name="PART_ContentPresenter"
                    Margin="{TemplateBinding Padding}"
                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                    Content="{TemplateBinding Content}"
                    ContentTemplate="{TemplateBinding ContentTemplate}"
                    RecognizesAccessKey="True" />
                </Border>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
    </Window.Styles>