'Avalonia style selector doen't works on derived classes

I'm having an issue to style my custom control derived from button.

I inherited the Button class to add a DependencyProperty to it:

public class IconButton : Button, IStyleable
{
    Type IStyleable.StyleKey => typeof(Button);

    public static readonly StyledProperty<string> IconProperty =
        AvaloniaProperty.Register<IconButton, string>(nameof(Icon));

    public string Icon
    {
        get { return GetValue(IconProperty); }
        set { SetValue(IconProperty, value); }
    }
}

Now I want to create a style targetting only this derived class:

<Styles xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="clr-namespace:Projektanker.Icons.Avalonia;assembly=Projektanker.Icons.Avalonia"
        xmlns:cc="*****.*****.CustomControls">
    <Design.PreviewWith>
        <Border Padding="20">
          <StackPanel Orientation="Vertical">
            <cc:IconButton Content="hello custom" Icon="fab fa-github"/>
            <Button Content="hello"/>
          </StackPanel>
        </Border>
    </Design.PreviewWith>

  <Style Selector=":is(cc|IconButton)">
    <Setter Property="Background" Value="Red"/>
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate>
          <StackPanel Orientation="Horizontal">
            <i:Icon Value="{TemplateBinding Icon}" />
            <TextBlock Text="{TemplateBinding Content}" />
          </StackPanel>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</Styles>

enter image description here

AS you can see, the content is not my control template as the icon is not visible and the background is not red. Therefore I can't use my dependencyproperty.

Any suggestions or is it not supported by the language? I read on the documentation that is(****) for selector is intended to support derived type so I would expect my code to be working :(

Thx for help.



Solution 1:[1]

Try to remove IStyleable and your overriden StyleKey. You are telling the selector that it should look for a Button style and not your style.

Happy coding Tim

PS I cannot test it on my own right now, so if it doesn't work please tell me here.


Update: I just made a blank new project and tested your code. Once I remove the StyleKey, it works:

enter image description here

This is the modified IconButton:

public class IconButton : Button
{
    public static readonly StyledProperty<string> IconProperty =
        AvaloniaProperty.Register<IconButton, string>(nameof(Icon));
    
    public string Icon
    {
        get { return GetValue(IconProperty); }
        set { SetValue(IconProperty, value); }
    }
}

If you are able to upload a minimal sample on Github, I can have a look what may be wrong.


Update 2: Looking into your demo App I see that you use a third party icon lib. The lib requires you to configure a special service at start up, see: https://github.com/Projektanker/Icons.Avalonia#1-register-icon-providers-on-app-start-up

I send you a PR which fixes your issue.

enter image description here

Happy coding Tim

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1