如何在Avalonia中正确绑定DependencyProperty?模板控件悬停问题排查
问题描述
希望在自定义TemplateControl(NormalButton)中,当鼠标悬停时修改内部名为B的Border控件的背景色。以下是当前的XAML和后台代码,但XAML中有两处报错:
<Setter Property="HoverBackground" Value="Red"></Setter><Setter Property="Background" Value="{TemplateBinding HoverBackground}" />
现有代码
XAML代码
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="using:Sample.TemplateControls"> <Design.PreviewWith> <controls:NormalButton /> </Design.PreviewWith> <Style Selector="controls|NormalButton"> <!-- Set Defaults --> <Setter Property="Background" Value="Blue"></Setter> <Setter Property="HoverBackground" Value="Red"></Setter> <Setter Property="Template"> <ControlTemplate> <Border Name="B" Background="{TemplateBinding Background}"> <ContentPresenter></ContentPresenter> </Border> </ControlTemplate> </Setter> </Style> <Style Selector="controls|NormalButton:pointerover /template/ Border#B"> <Setter Property="Background" Value="{TemplateBinding HoverBackground}" /> </Style> </Styles>
后台C#代码
using Avalonia; using Avalonia.Controls; using Avalonia.Media; namespace Sample.TemplateControls { public class NormalButton : Button { public static readonly StyledProperty<Brush> HoverBackgroundProperty = AvaloniaProperty.Register<Border, Brush>(nameof(HoverBackground)); public Brush HoverBackground { get { return GetValue(HoverBackgroundProperty); } set { SetValue(HoverBackgroundProperty, value); } } } }
错误原因及修正方案
1. 自定义属性注册错误
后台代码中注册HoverBackgroundProperty时,泛型参数错误地指定为Border,但这个属性属于NormalButton控件,而非Border。Avalonia无法识别归属其他控件的属性,导致XAML中设置HoverBackground时报错。
修正后的后台属性注册代码:
public static readonly StyledProperty<Brush> HoverBackgroundProperty = AvaloniaProperty.Register<NormalButton, Brush>(nameof(HoverBackground));
2. 模板绑定上下文错误
在针对Border#B的悬停样式中,{TemplateBinding HoverBackground}无法正确工作——因为TemplateBinding默认绑定当前目标元素(这里是Border)的属性,而HoverBackground属于父级的NormalButton。需要通过RelativeSource指定绑定到模板的父控件(即NormalButton)。
修正后的XAML悬停样式代码:
<Style Selector="controls|NormalButton:pointerover /template/ Border#B"> <Setter Property="Background" Value="{Binding HoverBackground, RelativeSource={RelativeSource TemplatedParent}}" /> </Style>
完整修正代码
后台C#代码
using Avalonia; using Avalonia.Controls; using Avalonia.Media; namespace Sample.TemplateControls { public class NormalButton : Button { public static readonly StyledProperty<Brush> HoverBackgroundProperty = AvaloniaProperty.Register<NormalButton, Brush>(nameof(HoverBackground)); public Brush HoverBackground { get { return GetValue(HoverBackgroundProperty); } set { SetValue(HoverBackgroundProperty, value); } } } }
XAML代码
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="using:Sample.TemplateControls"> <Design.PreviewWith> <controls:NormalButton /> </Design.PreviewWith> <Style Selector="controls|NormalButton"> <!-- Set Defaults --> <Setter Property="Background" Value="Blue"></Setter> <Setter Property="HoverBackground" Value="Red"></Setter> <Setter Property="Template"> <ControlTemplate> <Border Name="B" Background="{TemplateBinding Background}"> <ContentPresenter></ContentPresenter> </Border> </ControlTemplate> </Setter> </Style> <Style Selector="controls|NormalButton:pointerover /template/ Border#B"> <Setter Property="Background" Value="{Binding HoverBackground, RelativeSource={RelativeSource TemplatedParent}}" /> </Style> </Styles>
内容的提问来源于stack exchange,提问作者Melon NG
相关产品推荐
相关产品推荐

