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

调用DisplayPromptAsync后SelectedItem变量被置空的问题求助

问题:执行DisplayPromptAsync后SelectedItem变量被置为null

我完全搞不懂为什么SelectedItem变量会变成null。这个对象本来已经赋值了,但调用DisplayPromptAsync之后就被置空了。之前从来没碰到过这种问题,不知道该怎么排查。

操作演示动图

相关代码如下:

async void OpenContainerItem()
{
    // Pause the timer
    blnTimerActive = false;
    if (SelectedItem != null)
    {
        if (SelectedItem.intQuanChecked == SelectedItem.intQuantity)
            return;
        try
        {
            int intQuantity = 0;
            // Ask for quantity
            string result = await Application.Current.MainPage.DisplayPromptAsync("Quantity",
            "How many " + SelectedItem.objItem.strItemName + " did you count?",
            "Okay", cancel: "Cancel",
            placeholder: "Quantity",
            keyboard: Keyboard.Numeric);

            // Check if it's been cancelled
            if (result != null)
            {
                // check if theres nothing entered
                if (result == "")
                {
                    // Why tho?
                    await Application.Current.MainPage.DisplayAlert("Error", "Please enter a quantity.", "Okay");
                }
                else
                {
                    intQuantity = int.Parse(result);

                    if (0 > ((SelectedItem.intQuantity - SelectedItem.intQuanChecked) - intQuantity))
                    {
                        Application.Current.MainPage.DisplayAlert("Error", "Thats too many items!", "Okay");
                        Reload();
                        blnTimerActive = true;
                        return;
                    }

                    modDatabaseUtilities.ContainerItemsPreCheck(SelectedItem.intContainerItemID, intQuantity, strCurrentUser);
                    Reload();
                }
            }
        }
        catch(Exception ex)
        {
            Application.Current.MainPage.DisplayAlert("Error", "Couldn't process this change. Please try again.", "Okay");
        }
        
    }
}

排查方向与解决方法

1. 缓存SelectedItem避免UI绑定重置

DisplayPromptAsync会触发UI线程状态更新,如果SelectedItem是绑定到UI控件的属性,弹窗关闭后UI重新绑定可能导致原对象被重置。解决思路是调用弹窗前先把SelectedItem缓存到局部变量,后续操作都引用这个缓存:

async void OpenContainerItem()
{
    // 提前缓存当前选中项
    var currentSelectedItem = SelectedItem;
    blnTimerActive = false;
    if (currentSelectedItem != null)
    {
        if (currentSelectedItem.intQuanChecked == currentSelectedItem.intQuantity)
            return;
        try
        {
            int intQuantity = 0;
            string result = await Application.Current.MainPage.DisplayPromptAsync("Quantity",
            "How many " + currentSelectedItem.objItem.strItemName + " did you count?",
            "Okay", cancel: "Cancel",
            placeholder: "Quantity",
            keyboard: Keyboard.Numeric);

            if (result != null)
            {
                if (result == "")
                {
                    await Application.Current.MainPage.DisplayAlert("Error", "Please enter a quantity.", "Okay");
                }
                else
                {
                    intQuantity = int.Parse(result);

                    if (0 > ((currentSelectedItem.intQuantity - currentSelectedItem.intQuanChecked) - intQuantity))
                    {
                        Application.Current.MainPage.DisplayAlert("Error", "Thats too many items!", "Okay");
                        Reload();
                        blnTimerActive = true;
                        return;
                    }

                    modDatabaseUtilities.ContainerItemsPreCheck(currentSelectedItem.intContainerItemID, intQuantity, strCurrentUser);
                    Reload();
                }
            }
        }
        catch(Exception ex)
        {
            Application.Current.MainPage.DisplayAlert("Error", "Couldn't process this change. Please try again.", "Okay");
        }
    }
}

2. 检查Reload()方法的影响

代码中调用的Reload()方法可能会重新加载数据源,导致原来的SelectedItem对象脱离数据源,进而被置为null。可以查看Reload()的实现逻辑,确认是否需要在重新加载后恢复选中状态,或者调整该方法的调用时机。

3. 修正异步方法签名

当前方法用了async void,这种签名多用于事件处理,容易导致上下文丢失或异常无法捕获。建议改成async Task,调用时使用await OpenContainerItem(),避免异步操作的上下文异常:

async Task OpenContainerItem()
{
    // 方法逻辑不变,仅修改签名
}

内容的提问来源于stack exchange,提问作者Scott Uphus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:25:19