Prism Forms移除OnNavigatingTo后,如何在View构造前执行代码?
解决Prism Forms中View构造函数前运行代码的问题
针对你遇到的Prism移除OnNavigatingTo后,Promotion属性未初始化导致CanEditPromotion方法崩溃的问题,这里有几个可行的解决方案:
方案1:使用Prism的ObservableCommand自动处理CanExecute评估
Prism提供的ObservableCommand(替代DelegateCommand)能自动监听依赖属性的变化,当Promotion赋值完成后,它会自动重新执行CanEditPromotion方法,无需手动触发,非常适配这类场景。
修改后的ViewModel代码如下:
public ObservableCommand DeletePromotionCommand { get; set; } public ObservableCommand EditPromotionCommand { get; set; } public PromotionDetailViewModel(INavigationService navigationService, IPageDialogService pageDialogService) : base(navigationService, pageDialogService) { Title = "Promoção"; // 用ObservableCommand替代DelegateCommand,自动跟踪属性变化 DeletePromotionCommand = new ObservableCommand(DeletePromotion, CanDeletePromotion); EditPromotionCommand = new ObservableCommand(EditPromotion, CanEditPromotion); } private bool CanEditPromotion() { // 先处理Promotion为null的边界情况 if (Promotion == null) return false; var userString = Preferences.Get("user", string.Empty); if (userString == string.Empty) return false; var userId = (Guid)JObject.Parse(userString)["id"]; return userId == Promotion.CreatedBy; } // 确保Promotion是Observable属性,触发PropertyChanged通知 private Promotion _promotion; public Promotion Promotion { get => _promotion; set => SetProperty(ref _promotion, value); } // 在IInitialize的Initialize方法中完成参数接收与属性赋值 public override async void Initialize(INavigationParameters parameters) { base.Initialize(parameters); try { IsBusy = true; Promotion = parameters["promotion"] as Promotion; var marketService = new Service<Market>(); Market = await marketService.GetAsync(Promotion.MarketId); } catch (Exception) { // 这里可以添加具体的异常处理逻辑,比如弹窗提示 } finally { IsBusy = false; } }
方案2:延迟初始化DelegateCommand
如果不想更换命令类型,可以把DelegateCommand的初始化延迟到Promotion赋值完成之后,比如放在Initialize方法里:
public DelegateCommand DeletePromotionCommand { get; set; } public DelegateCommand EditPromotionCommand { get; set; } public PromotionDetailViewModel(INavigationService navigationService, IPageDialogService pageDialogService) : base(navigationService, pageDialogService) { Title = "Promoção"; // 构造函数中暂不初始化命令 } public override async void Initialize(INavigationParameters parameters) { base.Initialize(parameters); try { IsBusy = true; Promotion = parameters["promotion"] as Promotion; var marketService = new Service<Market>(); Market = await marketService.GetAsync(Promotion.MarketId); // 此时Promotion已赋值,再初始化命令 DeletePromotionCommand = new DelegateCommand(DeletePromotion, CanDeletePromotion); EditPromotionCommand = new DelegateCommand(EditPromotion, CanEditPromotion); } catch (Exception) { // 异常处理逻辑 } finally { IsBusy = false; } }
方案3:手动触发CanExecute重新评估
保持DelegateCommand在构造函数中初始化,但修改CanEditPromotion处理Promotion为null的情况,然后在Promotion赋值后手动调用命令的RaiseCanExecuteChanged方法:
public DelegateCommand DeletePromotionCommand { get; set; } public DelegateCommand EditPromotionCommand { get; set; } public PromotionDetailViewModel(INavigationService navigationService, IPageDialogService pageDialogService) : base(navigationService, pageDialogService) { Title = "Promoção"; DeletePromotionCommand = new DelegateCommand(DeletePromotion, CanDeletePromotion); EditPromotionCommand = new DelegateCommand(EditPromotion, CanEditPromotion); } private bool CanEditPromotion() { if (Promotion == null) return false; // 处理null边界 var userString = Preferences.Get("user", string.Empty); if (userString == string.Empty) return false; var userId = (Guid)JObject.Parse(userString)["id"]; return userId == Promotion.CreatedBy; } private Promotion _promotion; public Promotion Promotion { get => _promotion; set { if (SetProperty(ref _promotion, value)) { // 赋值完成后手动触发命令的CanExecute重新评估 EditPromotionCommand?.RaiseCanExecuteChanged(); DeletePromotionCommand?.RaiseCanExecuteChanged(); } } } public override async void Initialize(INavigationParameters parameters) { base.Initialize(parameters); try { IsBusy = true; Promotion = parameters["promotion"] as Promotion; var marketService = new Service<Market>(); Market = await marketService.GetAsync(Promotion.MarketId); } catch (Exception) { // 异常处理逻辑 } finally { IsBusy = false; } }
推荐优先使用方案1,因为ObservableCommand是Prism专门为这类依赖属性变化的场景设计的,能减少手动代码,更贴合MVVM的设计规范。
内容的提问来源于stack exchange,提问作者Sérgio Damasceno
相关产品推荐
相关产品推荐

