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

Xamarin中Telerik ListView滑动展开时如何强制重绘当前项

问题场景

为搭建最小可复现示例,已创建完成绑定的Record类,当列表项被滑动时会显示[$]按钮。点击该按钮可正常关闭滑动状态,更新列表项的参考代码如下:

public ICommand ClickCommand { get; }
private void OnClick(Record record) => onToggle(record);

bool _toggled = false;
private void onToggle(Record record)
{
    _toggled = !_toggled;
    if(_toggled)
    {
        Title = "Toggled";
        BackgroundColor = Color.LightSalmon;
    }
    else
    {
        Title = "Normal";
        BackgroundColor = Color.Transparent;
    }
    ListView.EndItemSwipe();
}

自动关闭流程示意图

经测试绑定逻辑本身正常,但实际需要实现的效果是:保持项的滑动展开状态,让卡片的背景色立即生效。注释掉ListView.EndItemSwipe();代码后,滑动状态可保持展开,此时点击[$]按钮仅会重绘按钮本身,卡片不会触发重绘,只有点击卡片关闭滑动状态后才会刷新:
保持展开状态流程示意图

核心诉求:当列表项仍处于滑动展开状态时,如何强制刷新项卡片,即在操作触发的第3帧而非关闭滑动后的第4帧完成重绘?


解决方法

这是ListView滑动交互的默认机制导致的:项处于滑动展开状态时,框架会优先响应滑动操作区的UI更新,主内容区的属性变更通知会被暂时挂起,直到滑动状态完全退出才会批量执行重绘。不需要修改控件源码,通过以下方式即可实现展开状态下的立即刷新:

  • 单元素强制重绘(性能最优)
    点击按钮完成业务属性赋值后,获取当前项对应的ViewCell实例,调用ForceLayout()方法强制该单元格立即执行布局和重绘,不需要调用EndItemSwipe()关闭滑动状态。参考修改后的代码:
    // 点击命令传参时可直接携带当前项索引,也可通过数据源查找对应索引
    int recordIndex = Records.IndexOf(record);
    if (ListView.TemplatedItems.GetOrCreateContent(recordIndex, record) is ViewCell targetCell)
    {
        targetCell.ForceLayout();
        // 安卓平台下如果上述调用不生效,额外调用原生视图的Invalidate方法即可
    #if ANDROID
        (targetCell.Handler?.PlatformView as Android.Views.View)?.Invalidate();
    #endif
    }
    
    该方法只会重绘当前操作的单个项,不会影响其他列表项的滑动状态,性能开销最小。
  • MVVM适配方案
    如果不想在后台代码中查找控件实例,可以给绑定的Record模型增加一个RefreshVersion整型属性,每次修改卡片业务属性时同步对该值+1;再给列表项的根容器添加绑定触发器,监听RefreshVersion的变更,触发时自动调用自身的ForceLayout()方法即可,逻辑和上述方法一致,不需要编写后台控件查找逻辑。

避坑提示:不要通过重新赋值ItemsSource、调用列表全局刷新方法实现需求,这类操作会重置所有列表项的滑动状态,性能损耗也远大于单元素强制重绘。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 04:57:43