WPF自定义NavButton控件绑定Material Icons遇类型转换错误求助
我开发了一个继承自ListBoxItem的自定义NavButton控件,用于承载面板名称和图标,同时设置了触发器实现鼠标悬停或选中时的颜色切换效果。但在主程序调用该控件时,始终出现类型转换错误。
自定义NavButton控件代码
public class NavButton : ListBoxItem { static NavButton() { DefaultStyleKeyProperty.OverrideMetadata(typeof(NavButton), new FrameworkPropertyMetadata(typeof(NavButton))); } public Uri NavLink { get { return (Uri)GetValue(NavLinkProperty); } set { SetValue(NavLinkProperty, value); } } // 存储导航目标的属性 public static readonly DependencyProperty NavLinkProperty = DependencyProperty.Register( "NavLink", typeof(Uri), typeof(NavButton), new PropertyMetadata(null)); // 存储图标的属性 public Label Icon { get { return (Label)GetValue(IconProperty); } set { SetValue(IconProperty, value); } } // 使用依赖属性作为Icon的后备存储,支持动画、样式、绑定等特性 public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(Label), typeof(NavButton), new PropertyMetadata(null)); }
主程序调用代码
<custom:NavButton Padding="6" FontFamily="{StaticResource Material}" Icon="{x:Static fonts:IconFont.VolumeHigh}"/>
图标资源字典配置
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <FontFamily x:Key="Material">/Fonts/Material.ttf#Material Design Icons</FontFamily> </ResourceDictionary>
控件样式代码
<Style TargetType="{x:Type local:NavButton}"> <Setter Property="HorizontalAlignment" Value="Center" /> <Setter Property="Cursor" Value="Hand" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:NavButton}"> <Border x:Name="back" Padding="{TemplateBinding Padding}" Background="Transparent" BorderBrush="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="8"> <Label x:Name="icon" Content="{TemplateBinding Icon}" FontFamily="{StaticResource Material}" FontSize="48" Foreground="#7b8793" /> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="back" Property="Background" Value="#d0ebff" /> <Setter TargetName="icon" Property="Foreground" Value="#2a84f1" /> </Trigger> <Trigger Property="IsSelected" Value="True"> <Setter TargetName="back" Property="Background" Value="#d0ebff" /> <Setter TargetName="icon" Property="Foreground" Value="#2a84f1" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
问题原因及解决方法
核心原因
类型转换错误源于Icon属性的类型定义与传入值不匹配:
XAML中传入的{x:Static fonts:IconFont.VolumeHigh}是字符类型(char),但自定义控件的Icon属性被定义为Label类型,导致无法将char转换为Label,触发类型转换异常。
修复步骤
- 修改自定义控件的Icon属性类型
将Icon属性的类型从Label改为char(或object,char更精准),因为我们实际需要的是图标的字符内容,而非Label控件本身。
修改后的控件代码:
public class NavButton : ListBoxItem { static NavButton() { DefaultStyleKeyProperty.OverrideMetadata(typeof(NavButton), new FrameworkPropertyMetadata(typeof(NavButton))); } public Uri NavLink { get { return (Uri)GetValue(NavLinkProperty); } set { SetValue(NavLinkProperty, value); } } public static readonly DependencyProperty NavLinkProperty = DependencyProperty.Register( "NavLink", typeof(Uri), typeof(NavButton), new PropertyMetadata(null)); // 修改为char类型,匹配传入的图标字符 public char Icon { get { return (char)GetValue(IconProperty); } set { SetValue(IconProperty, value); } } public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(char), // 此处改为char类型 typeof(NavButton), new PropertyMetadata('\0')); // 默认值设为空字符 }
样式代码无需修改
样式中的Label控件通过Content="{TemplateBinding Icon}"绑定Icon属性,char类型可直接作为Label的Content显示,无需额外调整。调用代码保持不变
原XAML调用代码无需修改,{x:Static fonts:IconFont.VolumeHigh}可正确绑定到char类型的Icon属性。
完成上述修改后,类型转换错误即可解决,控件能正常显示图标并触发样式触发器。
内容的提问来源于stack exchange,提问作者edu
相关产品推荐
相关产品推荐

