AvaloniaUI 样式 - 伪类

Posted

技术标签:

【中文标题】AvaloniaUI 样式 - 伪类【英文标题】:AvaloniaUI Styles-pseudoclasses 【发布时间】:2021-06-01 04:19:59 【问题描述】:

我正在尝试 avalonia 和大多数作品中的样式,除了伪类,它们只是被忽略了。

我创建了一个窗口,所有样式都在其中,并且我创建了一个用户控件(带有一个按钮 - 伪类在按钮上),使用样式。我不使用代码,只使用 xaml 来定义样式。

我已经在按钮的“样式选择器”中尝试了“Button:pseudoclassname”和“Button.le:pseudoclassname”。我也尝试过“Button:pointerover”和“Button:hover”,因为文档提到可以修改。没有结果。伪类的样式都被忽略了,其他的都被正确执行了。

是我做错了什么还是这是 avalonia 中的错误?

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>

【问题讨论】:

【参考方案1】:

ButtonBackground 属性确实会受到您的风格的影响,但此时它Button 的实际背景没有影响 , 因为Background 属性只控制按钮的正常状态。

如果您查看默认的Button 样式here,您可以看到它通过TemplateBinding 将其背景传递给ContentPresenter

    <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" />

由于实际绘制背景的是ContentPresenterButton 是一个无外观控件),因此您将看到具有ButtonBackgroundPointerOver 而不是ButtonBackground 属性值的按钮。

因此,您需要编写一个样式来更改内部 ContentPresenter ,如下所示:

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

不幸的是,这使您的样式依赖于主题,因为默认主题和流畅主题之间的控件模板不同。

【讨论】:

感谢您的解释 kekekeks !如果文档中提到了那将是很好的。但我还有一个问题。 fluent不是metro的继任者,所以只有microsoft/windows?我不明白为什么默认主题和流畅主题会有所不同?我唯一能想到的是,在后台 avalonia 仅在 Windows 上使用流利,而在其他平台上使用默认主题,这是一个正确的假设吗? 好的,我试过了,对于按钮,这很好用(我不得不修改一些属性名称,但它们可以在您指向的 avalonia/button.xaml 文件中找到。但如果我尝试以 TextBlock 为例,出现两个问题:1 - 控件目录中没有 TextBlock xaml 文件(您指出),所以不可能知道属性名称。2 - 如果我尝试例如 ,我没有收到错误,但它不起作用。我的属性没有被覆盖。 TextBlock 不是一个没有外观的控件,所以它没有模板。 Rider 应该在样式设置器中向您显示属性名称的补全。对于不太复杂的 IDE,您可以在 C# 编辑器中键入 TextBlock tb = null; tb.,它也会显示属性名称。 再次感谢 Kekekeks 的回答。我正在使用 Rider,我确实得到了建议,但我认为主要问题不是 IDE,而是我对 xaml 的了解不够。我在 Winforms、JavaFx、Spring 和 QML 方面有扎实的背景,但在 xaml (wpf/uwp) 方面没有。因此,我将首先学习有关 WPF 的课程(因为它是我读过的最接近 avalonia 的课程),然后从那里转到 avalonia(实际上我可能会在 Visual Studio 中的 WPF 和 Rider 中的 Avalona 并排学习它们)。【参考方案2】:

Kekekeks 给出的答案是我提出的问题的正确答案。

不过,我使用这个空间是希望像我一样帮助完全没有 xaml 背景的 avalonia 新手用户。我们大多数人都希望 avalonia 为我们的应用程序提供一个可在 Windows/Mac/Linux 上运行的界面。老实说,在撰写本文时,在 c# 中不存在真正的替代品。

目前,Avalonia 确实有一些很好的示例和一些文档,但对于那些没有 xaml 背景的人来说,情况并非如此。

因此,去 Udemy 或 LikedIn.Learning 或 Youtube 或任何你能找到关于 WPF 的好课程的地方,然后去 Avalonia 的文档并开始玩。

两者(Avalonia 和 WPF)的相似之处是巨大的!!! 是的,它在文档中提到过几次,但是 直言不讳“先去学习 WPF如果您是 xaml 的新手!”在文档的首页 会为我节省相当多的时间来尝试通过网站找到它。

公平是公平的,该项目仍处于测试阶段,并且该网站已经为该阶段提供了详细的文档,因此无需责怪团队!

【讨论】:

以上是关于AvaloniaUI 样式 - 伪类的主要内容,如果未能解决你的问题,请参考以下文章

伪类(伪类选择器)

常用伪类伪元素选择器

css中伪类/伪元素详解

CSS3详解伪元素与伪类

关于css伪类,伪元素详解总结

css3 伪类