WPF如何通过Bool类型DependencyProperty修改Rectangle背景色
问题根因
你的代码存在4个核心错误,导致绑定逻辑完全不生效:
- 依赖属性注册的所有者类型错误:你的控件类是
IdnStatusRect,但注册setSelectedPropert和BackgroundColorProperty时填写的所有者是IdxButton,依赖属性和控件不匹配。 BackgroundColor属性的get/set逻辑错误:get方法强转bool类型的setSelectedPropert值为Color,运行时必然抛出类型转换错误;set方法忽略传入值,强行写死为TextColor1资源,无法随选中状态更新。- 绑定目标类型不匹配:Rectangle的
Fill属性接收Brush类型值,你定义的BackgroundColor是Color类型,直接绑定会出现类型不匹配错误。 - XAML绑定位置错误:你需要修改的是Rectangle的填充效果,却把颜色绑定到了外层Grid的背景上,Rectangle本身的Fill属性写死为
Transparent,绑定的颜色根本不会显示。
推荐实现方案(纯XAML触发器,无冗余逻辑)
不需要额外定义BackgroundColor中转属性,直接通过控件模板的触发器监听setSelected状态,直接修改Rectangle的Fill值即可,逻辑最简单性能也最好。
修正后的后台控件代码
public class IdnStatusRect : Control { public bool SetSelected { get { return (bool)GetValue(SetSelectedProperty); } set { SetValue(SetSelectedProperty, value); } } // 修正依赖属性注册的所有者类型,遵循C#帕斯卡命名规则 public static readonly DependencyProperty SetSelectedProperty = DependencyProperty.Register(nameof(SetSelected), typeof(bool), typeof(IdnStatusRect), new FrameworkPropertyMetadata(false)); static IdnStatusRect() { DefaultStyleKeyProperty.OverrideMetadata(typeof(IdnStatusRect), new FrameworkPropertyMetadata(typeof(IdnStatusRect))); } }
修正后的Generic.xaml样式
<Style TargetType="{x:Type local:IdnStatusRect}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:IdnStatusRect}"> <Border Background="Transparent" BorderBrush="Purple" BorderThickness="0"> <DockPanel HorizontalAlignment="Center" VerticalAlignment="Center" Width="15" Height="15" Background="Transparent"> <Grid> <!-- 给Rectangle命名,供触发器定位 --> <Rectangle x:Name="PART_StatusRect" Width="15" Height="15" Fill="Transparent" Stroke="#97CDEB" StrokeThickness="1"/> </Grid> </DockPanel> <!-- 模板触发器直接监听选中状态切换颜色 --> <ControlTemplate.Triggers> <Trigger Property="SetSelected" Value="True"> <Setter TargetName="PART_StatusRect" Property="Fill" Value="Red"/> </Trigger> <Trigger Property="SetSelected" Value="False"> <Setter TargetName="PART_StatusRect" Property="Fill" Value="Transparent"/> </Trigger> </ControlTemplate.Triggers> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
扩展方案(保留BackgroundColor属性支持自定义颜色)
如果后续需要开放颜色配置能力,允许使用者自定义选中/未选中的填充色,可以修正BackgroundColor属性逻辑,通过依赖属性回调同步状态:
public class IdnStatusRect : Control { public bool SetSelected { get { return (bool)GetValue(SetSelectedProperty); } set { SetValue(SetSelectedProperty, value); } } public static readonly DependencyProperty SetSelectedProperty = DependencyProperty.Register(nameof(SetSelected), typeof(bool), typeof(IdnStatusRect), new FrameworkPropertyMetadata(false, OnSelectedStateChanged)); // 注意属性类型改为Brush,和Rectangle.Fill的类型匹配 public Brush BackgroundColor { get { return (Brush)GetValue(BackgroundColorProperty); } set { SetValue(BackgroundColorProperty, value); } } public static readonly DependencyProperty BackgroundColorProperty = DependencyProperty.Register(nameof(BackgroundColor), typeof(Brush), typeof(IdnStatusRect), new PropertyMetadata(Brushes.Transparent)); private static void OnSelectedStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = d as IdnStatusRect; if (control == null) return; control.BackgroundColor = (bool)e.NewValue ? Brushes.Red : Brushes.Transparent; } static IdnStatusRect() { DefaultStyleKeyProperty.OverrideMetadata(typeof(IdnStatusRect), new FrameworkPropertyMetadata(typeof(IdnStatusRect))); } }
对应XAML中直接绑定Rectangle的Fill属性即可:
<Rectangle Width="15" Height="15" Fill="{Binding BackgroundColor, RelativeSource={RelativeSource TemplatedParent}}" Stroke="#97CDEB" StrokeThickness="1"/>
内容的提问来源于stack exchange,提问作者user19555205
相关产品推荐
相关产品推荐

