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
相关产品推荐
相关产品推荐

