Стили AvaloniaUI-псевдоклассы

Я пробую стили в авалонии, и большинство работ, за исключением псевдоклассов, просто игнорируются.

Я создал окно, и все стили там, и я создал пользовательский элемент управления (с кнопкой - псевдоклассы на кнопке), используя стили. Я не использую код, только xaml для определения стилей.

Я попробовал это в селекторе стилей для кнопки как Button:pseudoclassname и Button.le:pseudoclassname. Я также пробовал Button:pointerover и Button:hover, поскольку в документации упоминается, что это можно изменить. Безрезультатно. Все стили для псевдоклассов игнорируются, все остальные выполняются корректно.

Я что-то делаю не так или это баг в Авалонии?

XAML-файл Windows:

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:views="clr-namespace:Hub.Views"
        xmlns:vm="using:Hub.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="Hub.Views.MainWindow"
        Icon="/Assets/avalonia-logo.ico"
        Width="200" Height="300"
        Title="Hub"
        Classes="le">

    <Window.Styles>
        <Style Selector="Window.le">
            <Setter Property="Background" Value="#191919"/>
        </Style>
        <Style Selector="Button.le">
            <Setter Property="Background" Value="green"/>
            <Setter Property="Foreground" Value="white"/>
        </Style>
        <Style Selector="Button.le:pointerover">
            <Setter Property="Background" Value="red"/>
            <Setter Property="Foreground" Value="white"/>
        </Style>
        <Style Selector="Button.le:pressed">
            <Setter Property="Background" Value="blue"/>
            <Setter Property="Foreground" Value="white"/>
        </Style>
        <Style Selector="TextBlock.le_update">
            <Setter Property="FontStyle" Value="Italic"/>
            <Setter Property="FontSize" Value="17"/>
            <Setter Property="FontFamily" Value="Arial, Verdana"/>
            <Setter Property="Foreground" Value="white"/>
            <Setter Property="Background" Value="transparent"/>
        </Style>
    </Window.Styles>
    
    <views:UpdateView/>

</Window>

Файл пользовательского управления xaml:

<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
             x:Class="Hub.Views.UpdateView">
    <DockPanel>
        <StackPanel DockPanel.Dock="Bottom">
            <Button Classes="le" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Width="300">
                Check for updates
            </Button>
        </StackPanel>
        <StackPanel Spacing="5" Margin="5">
            <TextBlock Classes="le_update" HorizontalAlignment="Center" Margin="4">
                No updates for Hub.
            </TextBlock>
            <TextBlock Classes="le_update" HorizontalAlignment="Center" Margin="4">
                No updates for Engine.
            </TextBlock>
        </StackPanel>
    </DockPanel>
</UserControl>


person Geertie    schedule 02.03.2021    source источник


Ответы (2)


Свойство Background Button действительно зависит от вашего стиля, но в этот момент оно не влияет на фактический фон Button, потому что свойство Background управляет только обычным em> состояние кнопки.

Если вы посмотрите на стиль Button по умолчанию здесь видно, что он передает свой фон ContentPresenter через TemplateBinding:

    <Setter Property="Template">
      <ControlTemplate>
        <ContentPresenter x:Name="PART_ContentPresenter"
                          Background="{TemplateBinding Background}"

но переопределяет фон ContentPresenter в следующем стиле:

  <Style Selector="Button:pointerover /template/ ContentPresenter#PART_ContentPresenter">
    <Setter Property="Background" Value="{DynamicResource ButtonBackgroundPointerOver}" />

Поскольку именно ContentPresenter на самом деле рисует фон (Button — это безликий элемент управления), вы увидите, что кнопка имеет ButtonBackgroundPointerOver, а не значение свойства Background Button.

Итак, вам нужно написать стиль, который изменяет внутренний ContentPresenter следующим образом:

<Style Selector="Button.le:pointerover /template/ ContentPresenter#PART_ContentPresenter">
  <Setter Property="Background" Value="green" />
</Style>

К сожалению, это делает ваши стили зависимыми от темы, поскольку шаблоны элементов управления различаются между темами по умолчанию и темами Fluent.

person kekekeks    schedule 02.03.2021
comment
Спасибо за объяснение кекекекс! Было бы неплохо, если бы это было упомянуто в документации. Но у меня есть еще один вопрос. Разве беглость не преемник метро, ​​поэтому только Microsoft/Windows? Я не понимаю, почему это будет отличаться между темами по умолчанию и беглыми темами? Единственное, о чем я могу думать, так это о том, что в фоновом режиме авалония использует бегло только на Windows и тему по умолчанию на других платформах, это правильное предположение? - person Geertie; 03.03.2021
comment
Хорошо, я попробовал это, и для кнопок это отлично работает (мне пришлось изменить имена некоторых свойств, но их можно найти в файле avalonia/button.xaml, на который вы указали. Но если я попытаюсь сделать это, например a TextBlock, возникают две проблемы: 1 - Нет xaml-файла TextBlock в каталоге элементов управления (на который вы указали), поэтому невозможно узнать имена свойств. 2 - Если я попытаюсь, например, ‹Setter Property=TextBlock.FontStyle Value=Italic/› , я не получаю ошибок, но это не работает Мое свойство не переопределяется. - person Geertie; 03.03.2021
comment
TextBlock не является безобразным элементом управления, поэтому для него нет шаблона. Rider должен показать вам завершение имен свойств в установщиках стилей. Для менее сложных IDE вы можете ввести TextBlock tb = null; tb. в редакторе C#, и он также покажет вам имена свойств. - person kekekeks; 04.03.2021
comment
Еще раз спасибо за ответ Кекекекс. Я использую Rider и получаю предложения, но я думаю, что основная проблема не в IDE, а в том, что я недостаточно знаю о xaml. У меня есть опыт работы с Winforms, JavaFx, Spring и QML, но не с xaml (wpf/uwp). Итак, я сначала пройду курс по WPF (поскольку он наиболее близок к авалонии, которую я читал), а затем перейду к авалонии (на самом деле я мог бы пройти их параллельно с WPF в Visual Studio и Avalona в Rider). - person Geertie; 04.03.2021

Ответ, который дал Кекекекс, является правильным ответом на вопрос, который я задал.

Тем не менее, я использую это пространство в надежде помочь начинающим пользователям авалонии, вообще не имеющим опыта работы с xaml, как это делаю я. Большинство из нас обращаются к Avalonia, чтобы предоставить нашим приложениям интерфейс, который работает на Windows/Mac/Linux. Честно говоря, на момент написания статьи реальных альтернатив в С# не существовало.

На данный момент у Avalonia есть примеры и некоторая документация, которые хороши, но не для людей, не имеющих опыта работы с xaml.

Поэтому зайдите на Udemy или LikedIn.Learning, или на Youtube, или везде, где вы найдете хороший курс по WPF, А ПОСЛЕ ЭТОГО перейдите к документации Avalonia и начните экспериментировать.

Общие сходства (Avalonia и WPF) огромны!!! И да, это несколько раз упоминается в документации, но тупое. Если вы новичок, сначала изучите WPF. в ксамл! на первой странице документации сэкономил бы мне немало времени, пытаясь найти все это через веб-сайт.

Справедливость есть справедливость, проект все еще находится в стадии бета-тестирования, и веб-сайт уже хорошо документирован для этой стадии, так что не вините команду!

person Geertie    schedule 06.03.2021