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

Xamarin.Forms登录页“记住我”勾选后列表重复加载问题求助

问题分析

你遇到的列表重复加载问题,核心原因是页面启动时的两次触发逻辑叠加:

  1. 首先pageStartFun调用fillDatabasePicker初始化数据库列表,若此时默认选中逻辑触发了SelectedDatabaseModel的属性变更,会自动触发公司列表加载;公司列表加载完成后,FirmaModel的默认值又会触发变电站列表加载。
  2. 随后执行beniHatirla,直接赋值SelectedDatabaseModel、FirmaModel、SubeModel,这又会再次触发各自的属性变更事件,导致列表加载逻辑重复执行。

另外你在beniHatirla里调用无参的OnPropertyChanged(),会通知所有属性变更,也会加剧不必要的UI刷新。

解决方案

方案1:添加初始化开关,屏蔽初始化阶段的事件触发

在ViewModel中新增一个布尔开关,在加载“记住我”缓存时禁用属性变更的触发逻辑,完成后再恢复:

private bool isInitializing = false;

async void pageStartFun()
{
    isInitializing = true; // 开启初始化开关,屏蔽事件触发
    fillDatabasePicker();
    await beniHatirla();
    isInitializing = false; // 关闭开关,恢复正常逻辑
}

// 改造SelectedDatabaseModel的属性 setter,添加开关判断
private DatabaseModel _selectedDatabaseModel;
public DatabaseModel SelectedDatabaseModel
{
    get => _selectedDatabaseModel;
    set
    {
        if (_selectedDatabaseModel != value)
        {
            _selectedDatabaseModel = value;
            OnPropertyChanged(nameof(SelectedDatabaseModel));
            // 初始化阶段不触发列表加载
            if (!isInitializing)
            {
                fillFirmaList(); // 填充公司列表的方法
            }
        }
    }
}

// 同理改造FirmaModel的属性 setter
private FirmaModel _firmaModel;
public FirmaModel FirmaModel
{
    get => _firmaModel;
    set
    {
        if (_firmaModel != value)
        {
            _firmaModel = value;
            OnPropertyChanged(nameof(FirmaModel));
            if (!isInitializing)
            {
                fillSubeList(); // 填充变电站列表的方法
            }
        }
    }
}

// 修正beniHatirla中的OnPropertyChanged,指定具体属性
async Task beniHatirla()
{
    hatirla = "hatirla";

    if (hatirla == "hatirla")
    {
        string db = Preferences.Get("myDB", "");
        DatabaseModel d = new DatabaseModel { DBKOD = db };
        FirmaModel f = new FirmaModel { FIRNO = fno };
        SubeModel s = new SubeModel { SUBEADI = subeAd };

        SelectedDatabaseModel = d;
        FirmaModel = f;
        SubeModel = s;
        Username = username;
        Password = pass;
        
        // 替换无参调用,只通知需要更新的属性
        OnPropertyChanged(nameof(Username));
        OnPropertyChanged(nameof(Password));
    }
}

方案2:调整执行顺序,先加载缓存再初始化列表

先读取“记住我”的缓存数据,再初始化Picker列表,这样初始化时直接选中缓存值,不会触发额外的变更事件:

async void pageStartFun()
{
    await beniHatirla(); // 先加载缓存数据
    fillDatabasePicker(); // 初始化数据库列表,此时SelectedDatabaseModel已设置,不会触发变更事件
    
    // 手动加载对应层级的列表
    if (SelectedDatabaseModel != null)
    {
        await fillFirmaList();
        if (FirmaModel != null)
        {
            await fillSubeList();
        }
    }
}

额外优化点

  • 你的fillSubeList方法中,OnPropertyChanged()应指定具体属性,避免全局刷新:
// 替换原来的OnPropertyChanged();
OnPropertyChanged(nameof(SubeList));
  • 若SubeList是ObservableCollection<SubeModel>类型,添加/移除项时会自动通知UI,无需手动调用OnPropertyChanged,可以直接去掉该调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 00:26:24