如何防止XAML类变量重置?解决页面重载时列表被重置问题
cartTitleListDisplay列表被重置的问题 嘿,你的问题我完全get到了——每次从Home跳转至Page3或者重载Page3时,之前存在cartTitleListDisplay里的数据就凭空消失了对吧?这其实是因为你现在的cartTitleListDisplay是Page3类的实例成员,每次页面重载都会新建一个Page3对象,这个新对象里的列表自然是重新new出来的空列表,之前的数据肯定留不住。
给你几个实用的解决办法,你可以根据自己的应用场景挑选:
1. 把列表改成静态变量(简单直接,适合小型项目)
把cartTitleListDisplay定义成静态成员,这样所有Page3的实例都会共享同一个列表,不管页面怎么重建,数据都能保留:
// 在Page3类里修改列表定义 private static List<string> cartTitleListDisplay = new List<string>();
⚠️ 注意:如果你的应用里可能同时存在多个Page3实例(比如导航栈里压了好几个),静态变量会让这些实例共享数据,可能出现意外情况,适合单实例使用的场景。
2. 启用页面导航缓存(让Page3实例被复用)
设置Page3的NavigationCacheMode,让系统复用之前的Page3实例,而不是每次都新建。你可以在Page3的构造函数里加这段代码:
public Page3() { InitializeComponent(); // Required表示强制缓存页面实例,Enabled表示在缓存可用时复用 this.NavigationCacheMode = NavigationCacheMode.Required; }
这样每次导航到Page3的时候,不会重新创建实例,原来的列表数据就保留下来了。如果需要根据新的导航参数更新数据,可以在OnNavigatedTo里判断导航类型,处理参数更新逻辑。
3. 用全局状态容器保存数据(规范的跨页面数据共享方式)
创建一个全局的状态类,专门用来存放需要跨页面、跨实例共享的数据:
// 全局状态类,可放在项目的Common文件夹等合适位置 public class AppGlobalState { // 单例模式,确保整个应用只有一个实例 public static AppGlobalState Instance { get; } = new AppGlobalState(); // 用来存你的购物车标题列表 public List<string> CartTitleList { get; set; } = new List<string>(); }
然后在Page3的OnNavigatedTo里改用这个全局列表:
protected override void OnNavigatedTo(NavigationEventArgs e) { List<string> cart1temp = e.Parameter as List<string>; if (cart1temp != null) { AppGlobalState.Instance.CartTitleList.AddRange(cart1temp); } // 先判断列表有没有数据,避免索引越界异常 if (AppGlobalState.Instance.CartTitleList.Count > 0) { cartTitle1.Text = AppGlobalState.Instance.CartTitleList[0]; // 这里你原来的代码里cartPrice1也用了[0],是不是笔误?建议检查一下逻辑 cartPrice1.Text = AppGlobalState.Instance.CartTitleList[0]; } }
这种方式不管Page3怎么重建,数据都存在全局状态里,不会丢失,适合中大型应用。
4. 结合MVVM用ViewModel存数据(推荐的规范开发方式)
如果你的项目用了MVVM模式,可以把列表放在Page3的ViewModel里,确保ViewModel的生命周期和页面无关(比如用单例或者依赖注入管理)。举个简单的例子:
public class Page3ViewModel : INotifyPropertyChanged { private List<string> _cartTitleListDisplay = new List<string>(); public List<string> CartTitleListDisplay { get => _cartTitleListDisplay; set { _cartTitleListDisplay = value; OnPropertyChanged(nameof(CartTitleListDisplay)); } } // 实现INotifyPropertyChanged接口的代码 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
然后通过依赖注入让ViewModel保持单例,或者导航时传递同一个ViewModel实例,这样页面重建时ViewModel还是原来的,数据自然不会丢。
另外提一句,你原来的代码里有个小风险:try块里的代码和外面的if重复了,而且如果列表为空的话,cartTitleListDisplay[0]会抛出索引越界异常,建议以后先检查列表的Count是否大于0再访问索引哦。
内容的提问来源于stack exchange,提问作者Console.WriteLine

