You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 18:48:26