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

使用MvvmCross绑定OxyPlot时,RecyclerView中InvalidatePlot不生效问题

嘿,我之前踩过MvvmCross绑定OxyPlot后刷新失效的坑,给你几个排查和解决的思路,应该能帮你搞定:

先检查核心绑定逻辑

首先得确保ViewModel和布局的绑定是正确的,这是刷新生效的基础:

1. ViewModel里的PlotModel属性要触发通知

你的ViewModel得继承MvxViewModel,并且PlotModel属性要通过SetProperty触发INotifyPropertyChanged,这样MvvmCross才能感知到变化并通知UI:

private PlotModel _classroomPlotModel;
public PlotModel ClassroomPlotModel
{
    get => _classroomPlotModel;
    set => SetProperty(ref _classroomPlotModel, value);
}

2. XML布局里的绑定要正确

假设你用的是Android布局,要确保PlotView的Model属性绑定到ViewModel对应的属性上,注意命名空间要正确引入:

<oxyplot.xamarin.android.PlotView
    android:id="@+id/classroom_plot"
    android:layout_width="match_parent"
    android:layout_height="250dp"
    local:MvxBind="Model ClassroomPlotModel" />
再看RecyclerView Adapter里的问题

因为你提到了ClassroomViewRecyclerAdapter.cs,这里很容易出现实例引用或线程问题:

1. 确保ViewHolder正确持有PlotView实例

在Adapter的ViewHolder里,要确保PlotView的引用没有为空,并且绑定完成后再操作:

public class ClassroomViewHolder : RecyclerView.ViewHolder
{
    public PlotView PlotView { get; private set; }

    public ClassroomViewHolder(View itemView) : base(itemView)
    {
        PlotView = itemView.FindViewById<PlotView>(Resource.Id.classroom_plot);
    }
}

2. 刷新操作必须在UI线程执行

OxyPlot的InvalidatePlot是UI操作,绝对不能在后台线程调用。在Adapter的OnBindViewHolder里,你可以用Post方法切换到UI线程:

public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
    var classroomHolder = holder as ClassroomViewHolder;
    var item = _dataList[position];

    // 完成MvvmCross绑定
    var bindingSet = this.CreateBindingSet<ClassroomViewRecyclerAdapter, ClassroomItem>();
    bindingSet.Bind(classroomHolder.PlotView).For(v => v.Model).To(item => item.PlotModel);
    bindingSet.Apply();

    // 手动刷新图表,确保在UI线程
    classroomHolder.PlotView.Post(() =>
    {
        classroomHolder.PlotView.Model?.InvalidatePlot(true);
    });
}
额外排查点
  • 如果是在ViewModel里更新PlotModel的数据(比如添加Series、修改数值),要先更新数据,再调用InvalidatePlot,并且同样要确保在UI线程:
    // 在ViewModel中更新数据后刷新
    await Mvx.IoCProvider.Resolve<IMvxMainThreadDispatcher>().ExecuteOnMainThreadAsync(() =>
    {
        ClassroomPlotModel.InvalidatePlot(true);
    });
    
  • 检查PlotModel是否被重复创建,导致绑定的实例和你刷新的实例不是同一个。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:47:41