使用Caliburn Micro MVVM时DataGrid编辑项未更新的问题
解决方案
1. 让数据模型支持属性变更通知
Caliburn Micro 提供了PropertyChangedBase基类,让CalibrationPoint继承它,这样属性值变化时能自动通知UI更新。同时在Start和Stop的setter中处理对应业务逻辑,以此区分用户编辑的是哪一列(修改Start触发Start属性的setter,修改Stop触发Stop属性的setter)。
修改后的CalibrationPoint代码:
public class CalibrationPoint : PropertyChangedBase { private int _no; private int _start; private int _stop; private double _estimatedCalibrationTime; public int No { get => _no; set => Set(ref _no, value); } public int Start { get => _start; set { if (Set(ref _start, value)) { // 编辑Start列时,重新计算预估校准时间 EstimatedCalibrationTime = CalculateCalibrationTime(_start, _stop); } } } public int Stop { get => _stop; set { if (Set(ref _stop, value)) { // 编辑Stop列时,重新计算Start值(示例用反推逻辑,可根据实际需求调整) // 假设保持预估时间不变,反推Start值 if (_estimatedCalibrationTime >= _stop * 1.2) { Start = (int)Math.Round((_estimatedCalibrationTime - _stop * 1.2) / 0.7); } else { // 处理数值不合理的情况,设置默认值 Start = 1; } // 重新计算预估时间(同步Start变化后的结果) EstimatedCalibrationTime = CalculateCalibrationTime(_start, _stop); } } } public double EstimatedCalibrationTime { get => _estimatedCalibrationTime; set => Set(ref _estimatedCalibrationTime, value); } private double CalculateCalibrationTime(int start, int stop) { return (start * 0.7) + (stop * 1.2); } }
2. 调整DataGrid绑定配置
在XAML中,为Start和Stop列的Binding添加UpdateSourceTrigger=PropertyChanged,确保单元格编辑时立刻同步到数据源,触发属性setter中的计算逻辑。
修改后的XAML相关列代码:
<DataGridTextColumn Header="start" Width="2*" Binding="{Binding Start, UpdateSourceTrigger=PropertyChanged}"> </DataGridTextColumn> <DataGridTextColumn Header="stop" Width="2*" Binding="{Binding Stop, UpdateSourceTrigger=PropertyChanged}"/>
关键说明
- 识别编辑列:无需额外判断列,通过属性的setter即可区分——编辑Start列会触发
Start属性的setter,编辑Stop列会触发Stop属性的setter,在各自逻辑块中执行对应计算即可。 - 自动更新UI:通过继承
PropertyChangedBase并使用Set方法(Caliburn Micro提供的便捷方法,自动触发PropertyChanged事件),确保属性变化后UI实时更新;UpdateSourceTrigger=PropertyChanged保证编辑动作立刻同步到数据源,触发计算逻辑。
补充:GridViewModel初始化简化
原初始化代码中无需手动计算EstimatedCalibrationTime,因为Start或Stop设置后会自动触发计算:
public GridViewModel() { CalibrationPoints = new BindableCollection<CalibrationPoint>(); CalibrationPoints.Add(new CalibrationPoint() { No = 1, Start = 1, Stop = 2 }); CalibrationPoints.Add(new CalibrationPoint() { No = 2, Start = 3, Stop = 5 }); CalibrationPoints.Add(new CalibrationPoint() { No = 3, Start = 6, Stop = 8 }); }
内容的提问来源于stack exchange,提问作者RBCSharp
相关产品推荐
相关产品推荐

