Oxyplot中PlotModel与PlotView的InvalidatePlot()区别及占用报错解决咨询
Oxyplot 常见问题解答
PlotModel.InvalidatePlot() 与 PlotView.InvalidatePlot() 的差异
PlotModel.InvalidatePlot():模型层刷新方法,调用后会标记PlotModel内部的系列、坐标轴、标注等数据已变更,通知所有关联的PlotView需要执行重绘。方法入参可指定是否更新数据:默认值为true时会重新计算所有数据点的渲染坐标,为false时仅重绘外观,不会重新计算数据。PlotView.InvalidatePlot():视图层刷新方法,仅触发当前PlotView控件的重绘操作,不会修改关联PlotModel的状态,适合仅视图层属性(如控件尺寸、透明度)变更时调用,不会联动模型层其他关联视图。
"This PlotModel is already in use by some other PlotView control." 错误解决方案
该错误的根因为Oxyplot的原生设计限制:单个PlotModel实例同一时间仅能绑定到一个PlotView控件,当PlotModel还保留上一个绑定的PlotView引用时,重复绑定到新的PlotView就会触发该报错。
可按优先级选择以下方案解决:
- 切换绑定前先主动解绑旧PlotModel
每次给绑定的PlotModel属性赋新值前,先将属性值设为null并触发属性变更通知,让PlotView和旧PlotModel解除关联后再赋值新模型,代码示例:
private PlotModel _selectedPlotModel; public PlotModel SelectedPlotModel { get => _selectedPlotModel; set { // 解绑旧模型 _selectedPlotModel = null; NotifyOfPropertyChanged(nameof(SelectedPlotModel)); // 赋值新模型 _selectedPlotModel = value; NotifyOfPropertyChanged(nameof(SelectedPlotModel)); } }
- 实体存储原始绘图数据,选中时动态生成PlotModel
修改实体结构,不再存储PlotModel实例,改为存储实验原始数据、系列配置、坐标轴参数等绘图所需的基础信息,每次选中实体时,基于这些信息重新构建PlotModel实例再赋值给绑定属性。该方案符合MVVM分层设计规范,从根源上避免PlotModel复用冲突。 - 手动清除PlotModel的关联视图引用
如果必须复用PlotModel实例,可以调用PlotModel的ClearPlotViews()方法手动清除所有关联的PlotView引用。如果你的Oxyplot版本中该方法为非公开方法,可通过反射调用:
// 先清除旧PlotModel的关联视图 if (_selectedPlotModel != null) { var clearMethod = typeof(PlotModel).GetMethod("ClearPlotViews", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); clearMethod?.Invoke(_selectedPlotModel, null); } // 再赋值新模型 _selectedPlotModel = value; NotifyOfPropertyChanged(nameof(SelectedPlotModel));
排查方向说明
该报错与InvalidatePlot()的调用逻辑无关,不需要将排查重点放在该方法上,核心解决思路为处理PlotModel的独占绑定限制即可。
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

