AvaloniaUI 样式-伪类

6

我正在尝试在Avalonia中使用样式,大多数都能正常工作,但伪类却被忽略了。

我创建了一个窗口,并将所有样式放在其中。我还创建了一个用户控件(上面有一个按钮),并使用这些样式。我只使用XAML来定义样式,没有使用代码。

我已经在按钮的“Style Selector”中尝试了"Button:pseudoclassname"和"Button.le:pseudoclassname"。我也尝试了"Button:pointerover"和"Button:hover",因为文档提到可以修改它们,但是没有效果。伪类的样式都被忽略了,其他样式都执行正确。

我是否做错了什么,还是Avalonia中存在问题?

XAML窗口文件:

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

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

2个回答

6

ButtonBackground 属性会受到样式的影响,但在此时它对实际的 Button 背景没有影响,因为 Background 属性只控制按钮的普通状态。

如果您查看默认的 Button 样式(请点击此处),您可以看到它通过 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}" />

因为实际上是ContentPresenter绘制背景(Button是一个无外观控件),所以您将看到按钮具有ButtonBackgroundPointerOver而不是ButtonBackground属性值。

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

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

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


谢谢你的解释 kekekeks!如果文档中提到这一点会更好。但我还有一个问题。Fluent不是Metro的继承者吗,所以只适用于Microsoft/Windows?我不明白为什么在默认和Fluent主题之间会有区别?我唯一能想到的是,在后台Avalonia仅在Windows上使用Fluent主题,而在其他平台上使用默认主题,这个假设正确吗? - Geertie
好的,我已经尝试过了,对于按钮来说,这个方法非常有效(我不得不修改一些属性名称,但是它们可以在你指向的avalonia/button.xaml文件中找到)。但是如果我尝试对例如TextBlock这样的控件进行操作,就会出现两个问题:1-在控件目录中没有TextBlock xaml文件(你指向的),因此无法知道属性名称。2-如果我尝试使用<Setter Property="TextBlock.FontStyle" Value="Italic"/>,我不会收到错误消息,但它不起作用。我的属性没有被覆盖。 - Geertie
TextBlock不是一个无外观控件,因此没有模板可用。Rider应该会在样式设置器中为属性名称显示自动完成。对于不太复杂的IDE,您可以在C#编辑器中键入“TextBlock tb = null; tb.”,它也会显示属性名称。 - kekekeks
再次感谢Kekekeks的回答。我正在使用Rider,我确实得到了建议,但我认为主要问题不是IDE,而是我对xaml了解不够。我在Winforms、JavaFx、Spring和QML方面有坚实的背景,但在xaml(wpf/uwp)方面却不行。因此,我将首先学习WPF课程(因为它是最接近avalonia的),然后从那里转到avalonia(我实际上可能会在Visual Studio中同时进行WPF和Rider中的Avalona)。 - Geertie

1
Kekekeks给出的答案是我提出的问题的正确答案。
然而,我希望利用这个空间来帮助那些像我一样没有任何xaml背景的avalonia入门用户。我们大多数人都希望使用avalonia为我们的应用程序提供在Windows/Mac/Linux上运行的界面。老实说,在编写时,c#中没有真正的替代品。
此时,Avalonia确实有一些好的示例和文档,但对于没有真正xaml背景的人来说并不是很好理解。
因此,去Udemy或LikedIn.Learning或Youtube或其他你能找到的关于WPF的好课程,之后再去Avalonia的文档中开始尝试。
两者(Avalonia和WPF)之间的相似之处非常巨大!是的,文档中提到了几次,但如果文档的首页直接明确地说“如果您是xaml新手,请先学习WPF!”那么就可以节省我大量时间在网站上寻找答案了。
公平是公平的,该项目仍处于测试阶段,网站已经为该阶段做好了充分的文档记录,因此不应责怪团队!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接