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

DataGrid模板中自定义CLightSystem控件Value属性为空问题排查

原因分析

  • 绑定时机不匹配:OnApplyTemplate执行时,DataGrid单元格的数据绑定可能还未完成,此时Value属性为空,调用UpdateLight()不会触发任何灯光状态变更。单独使用控件时,绑定完成早于模板应用,所以能正常工作,但DataGrid内的虚拟化加载逻辑会改变这个顺序。
  • 未监听属性变化:自定义控件仅在模板应用时执行一次UpdateLight(),当Value通过绑定获得有效值后,没有自动触发状态更新的逻辑。
  • 绑定路径可能存在问题:需确认CncCollectionM12中的数据项确实包含公共、名称完全匹配的StatusDrawing属性(WPF绑定大小写敏感),且属性值变化时能通知UI(实现INotifyPropertyChanged)。

解决方案

1. 为Value属性添加变更回调

修改依赖属性注册代码,添加PropertyChangedCallback,确保Value值变化时自动更新灯光状态:

public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
    "Value", typeof(string), typeof(CLightSystem), 
    new PropertyMetadata(default(string), OnValueChanged));

private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var control = d as CLightSystem;
    control?.UpdateLight();
}

2. 增强UpdateLight()的鲁棒性

添加空值和控件实例判断,避免空引用异常,同时处理未匹配到的Value情况,修正原代码中橙色灯光阴影颜色的错误:

public void UpdateLight()
{
    // 若控件实例未初始化或Value为空,重置为默认灰色
    if (redLight == null || orangeLight == null || greenLight == null || string.IsNullOrEmpty(Value))
    {
        redLight?.Fill = new SolidColorBrush(Colors.LightGray);
        orangeLight?.Fill = new SolidColorBrush(Colors.LightGray);
        greenLight?.Fill = new SolidColorBrush(Colors.LightGray);
        return;
    }

    switch (Value)
    {
        case "GESPERRT":
            redLight.Fill = new SolidColorBrush(Colors.Red);
            redLight.Effect = new DropShadowEffect()
            {
                Color = new Color { A = 255, R = 255, G = 0, B = 0 },
                BlurRadius = 3,
                Direction = -90,
                ShadowDepth = 0
            };
            // 重置其他灯光
            orangeLight.Fill = new SolidColorBrush(Colors.LightGray);
            orangeLight.Effect = null;
            greenLight.Fill = new SolidColorBrush(Colors.LightGray);
            greenLight.Effect = null;
            break;

        case "IN BEARBEITUNG":
            orangeLight.Fill = new SolidColorBrush(Colors.DarkOrange);
            orangeLight.Effect = new DropShadowEffect()
            {
                Color = new Color { A = 255, R = 255, G = 165, B = 0 },
                BlurRadius = 3,
                Direction = -90,
                ShadowDepth = 0
            };
            // 重置其他灯光
            redLight.Fill = new SolidColorBrush(Colors.LightGray);
            redLight.Effect = null;
            greenLight.Fill = new SolidColorBrush(Colors.LightGray);
            greenLight.Effect = null;
            break;

        case "FREIGEGEBEN":
            greenLight.Fill = new SolidColorBrush(Colors.Green);
            greenLight.Effect = new DropShadowEffect()
            {
                Color = new Color { A = 255, R = 0, G = 255, B = 0 },
                BlurRadius = 3,
                Direction = -90,
                ShadowDepth = 0
            };
            // 重置其他灯光
            redLight.Fill = new SolidColorBrush(Colors.LightGray);
            redLight.Effect = null;
            orangeLight.Fill = new SolidColorBrush(Colors.LightGray);
            orangeLight.Effect = null;
            break;

        default:
            // 默认情况重置所有灯光
            redLight.Fill = new SolidColorBrush(Colors.LightGray);
            redLight.Effect = null;
            orangeLight.Fill = new SolidColorBrush(Colors.LightGray);
            orangeLight.Effect = null;
            greenLight.Fill = new SolidColorBrush(Colors.LightGray);
            greenLight.Effect = null;
            break;
    }
}

3. 验证数据绑定的正确性

  • 确保CncCollectionM12中的数据项拥有公共无参数的StatusDrawing属性,名称拼写完全一致(包括大小写)。
  • 如果StatusDrawing值会动态变化,数据项需实现INotifyPropertyChanged接口:
public class CncDataItem : INotifyPropertyChanged
{
    private string _statusDrawing;
    public string StatusDrawing
    {
        get => _statusDrawing;
        set
        {
            if (_statusDrawing != value)
            {
                _statusDrawing = value;
                OnPropertyChanged(nameof(StatusDrawing));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

4. 可选:临时关闭DataGrid虚拟化(用于验证)

如果怀疑是虚拟化导致的绑定延迟,可以临时关闭虚拟化测试(长期使用会影响大数据量时的性能):

<DataGrid ... VirtualizingStackPanel.IsVirtualizing="False">

内容的提问来源于stack exchange,提问作者Leeeeeeevin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:00:56