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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:20:40