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

Xamarin.Forms UWP中DisplayActionSheet选择后反复弹出问题求助

问题:UWP平台Entry获焦触发DisplayActionSheet后反复弹出

我在Entry获得焦点时触发DisplayActionSheet,该功能在Android和iOS平台运行正常,但在UWP平台中,选择选项后操作表不会消失,而是持续反复弹出。相关代码如下:

async private void edlevel_Focused(object sender, FocusEventArgs e)
{
    urlClass urldata = new urlClass();
    string uri = urldata.url + "/GetAllEdlevels/4";
    try
    {
        HttpResponseMessage responsepost = await client.GetAsync(uri);

        if (responsepost.IsSuccessStatusCode == true)
        {
            string outcome = await responsepost.Content.ReadAsStringAsync();
            var result = JsonConvert.DeserializeObject<List<edlevels>>(outcome);

            string[] edlevels_lst = new string[result.Count];
            for (int i = 0; i < result.Count; i++)
            {
                edlevels_lst[i] = result[i].edlevel;
            }

            string action = await DisplayActionSheet("Education Levels", "OK", null, edlevels_lst);
            if (action == "OK")
            {
                edlevel.Text = "";
            }
            else
            {
                edlevel.Text = action;
            }
            if(!string.IsNullOrEmpty(edlevel.Text))
            { 
                if (edlevel.Text.Trim() == "Kgs" || edlevel.Text.Trim() == "Nursery")
                {
                    discount.IsToggled = false;
                    discount.IsEnabled = false;
                }
                else
                {
                    discount.IsEnabled = true;
                }
            }
        }
        else
        {
            await DisplayAlert("Operation Failed", "Response Failed!", "Cancel");
        }
    }
    catch (System.Net.WebException exp)
    {
        bool ans = await DisplayAlert("Connection Failed", "Please Check Your Internet Connection!", "Retry", "Cancel");
        if (ans == true)
            edlevel_Focused(sender, e);
    }
    catch (Exception exp)
    {
        bool ans = await DisplayAlert("Connection Failed", "Lost Connection!", "Retry", "Cancel");
        if (ans == true)
            edlevel_Focused(sender, e);
    }
}
问题原因与解决方法

原因分析

UWP平台的焦点行为和移动平台存在差异:当DisplayActionSheet弹出时,Entry会失去焦点;操作表关闭后,Entry会自动重新获得焦点,再次触发Focused事件,形成循环。另外,代码中直接递归调用edlevel_Focused的重试逻辑,会进一步加剧这个循环问题。

解决步骤

  • 临时移除事件绑定,避免重复触发
    在弹出操作表前,先移除Entry的Focused事件监听,操作完成后再重新绑定。用try-finally确保无论成功还是失败,事件都会重新绑定,避免后续无法触发。
  • 替换递归重试逻辑
    不要直接递归调用edlevel_Focused,改为手动触发Entry的焦点,让事件正常触发。
  • 手动控制焦点(可选)
    操作完成后,可以将焦点转移到其他控件,或者根据需求决定是否让Entry重新获焦。

修改后的代码示例

async private void edlevel_Focused(object sender, FocusEventArgs e)
{
    // 先移除事件绑定,避免重复触发
    edlevel.Focused -= edlevel_Focused;
    urlClass urldata = new urlClass();
    string uri = urldata.url + "/GetAllEdlevels/4";
    try
    {
        HttpResponseMessage responsepost = await client.GetAsync(uri);

        if (responsepost.IsSuccessStatusCode == true)
        {
            string outcome = await responsepost.Content.ReadAsStringAsync();
            var result = JsonConvert.DeserializeObject<List<edlevels>>(outcome);

            // 简化数组转换逻辑
            string[] edlevels_lst = result.Select(item => item.edlevel).ToArray();

            string action = await DisplayActionSheet("Education Levels", "OK", null, edlevels_lst);
            if (action == "OK")
            {
                edlevel.Text = "";
            }
            else
            {
                edlevel.Text = action;
            }
            
            if(!string.IsNullOrEmpty(edlevel.Text))
            { 
                bool isPreSchool = edlevel.Text.Trim() is "Kgs" or "Nursery";
                discount.IsToggled = false;
                discount.IsEnabled = !isPreSchool;
            }
        }
        else
        {
            await DisplayAlert("Operation Failed", "Response Failed!", "Cancel");
        }
    }
    catch (System.Net.WebException exp)
    {
        bool ans = await DisplayAlert("Connection Failed", "Please Check Your Internet Connection!", "Retry", "Cancel");
        if (ans == true)
        {
            // 手动触发焦点,让事件重新触发
            edlevel.Focus();
        }
    }
    catch (Exception exp)
    {
        bool ans = await DisplayAlert("Connection Failed", "Lost Connection!", "Retry", "Cancel");
        if (ans == true)
        {
            edlevel.Focus();
        }
    }
    finally
    {
        // 无论成功失败,重新绑定事件
        edlevel.Focused += edlevel_Focused;
    }
}

内容的提问来源于stack exchange,提问作者rana hd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:31:25