You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

AutoSuggestBox在LosingFocus与LostFocus事件间丢失输入值的问题求助

AutoSuggestBox在LosingFocus与LostFocus事件间丢失输入值的问题求助

我遇到了一个十分棘手的问题:当从某个特定的AutoSuggestBox中按Tab键切换焦点时,它的输入值会在LosingFocusLostFocus事件之间被莫名清空。

更奇怪的是,这个问题只出现在我应用里的这一个AutoSuggestBox实例上,其他功能类似甚至配置完全相同的AutoSuggestBox都能正常工作,完全没这个问题。

最小可复现示例

XAML代码

<AutoSuggestBox Text="{x:Bind ViewModel.Value, Mode=TwoWay}" 
                 ItemsSource="{x:Bind ViewModel.VisibleValues, Mode=OneWay}" 
                 TextMemberPath="TextMember" DisplayMemberPath="TextMember"
                 LosingFocus="TestLosingFocus" LostFocus="TestLostFocus" />

C#事件处理代码

// ...
private void TestLosingFocus(UIElement sender, LosingFocusEventArgs args)
{
    string senderText = (sender as AutoSuggestBox).Text; // 此时值为输入的"abc"
    string vmText = ViewModel.Value; // 此时ViewModel的值也是"abc"
}

private void TestLostFocus(object sender, RoutedEventArgs e)
{
    string senderText = (sender as AutoSuggestBox).Text; // 此时值为空字符串""
    string vmText = ViewModel.Value; // ViewModel的值也变成了""
}
// ...

复现步骤:在AutoSuggestBox中输入任意内容,然后按Tab键切换到Tab顺序中的下一个控件。值得注意的是,如果用鼠标点击其他控件移除焦点,就不会触发这个bug。

问题发生的详细过程

  1. LosingFocus事件阶段:按下Tab键切换焦点时,AutoSuggestBox先触发LosingFocus事件,此时控件的Text属性和ViewModel的Value值都和输入内容完全一致,一切正常。
  2. 生成代码执行阶段:单步调试跳出TestLosingFocus方法后,会执行一段WinRT生成代码中的函数(不会进入catch块),而且调试器无法单步进入try块内的语句,只能直接跳过。这段代码如下:
namespace WinRT.GenericTypeInstantiations;

// ...

internal static class Windows_Foundation_TypedEventHandler_2_Microsoft_UI_Xaml_UIElement__Microsoft_UI_Xaml_Input_LosingFocusEventArgs
{
// ...
        [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })]
        private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr args)
        {
            try
            {
                global::ABI.Windows.Foundation.TypedEventHandlerMethods<global::Microsoft.UI.Xaml.UIElement, IntPtr, global::Microsoft.UI.Xaml.Input.LosingFocusEventArgs, IntPtr>.Abi_Invoke(thisPtr, global::ABI.Microsoft.UI.Xaml.UIElement.FromAbi(sender), global::ABI.Microsoft.UI.Xaml.Input.LosingFocusEventArgs.FromAbi(args));

            }
            catch (Exception __exception__)
            {
                global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__);
                return global::WinRT.ExceptionHelpers.GetHRForException(__exception__);
            }
            return 0;
        }
// ...
}
  1. ViewModel值被清空阶段:紧接着,ViewModel.Value的setter会被触发——这个断点无法通过单步调试到达,只能单独设置断点才能捕获到。此时传入的赋值是空字符串,而且调用栈里能看到刚才那段生成代码的调用记录。
  2. LostFocus事件阶段:跳出生成函数后,AutoSuggestBox触发LostFocus事件,此时再检查就会发现控件的Text和ViewModel的Value都已经变成空字符串了。

我已经尝试过的排查方法

我试过移除这个AutoSuggestBox上所有的事件处理方法、自定义样式,以及任何可能影响它的配置项;另外也把项目中所有可能修改ViewModel.Value的代码都逐一删除了,但不管怎么调整,问题依然存在。这个bug已经困扰我快一个月了,实在找不到突破口,希望能得到大家的帮助。

备注:内容来源于stack exchange,提问作者Josh Brunton

火山引擎 最新活动