【问题标题】:crash in ComboBox coerce (not my code)在 ComboBox 强制中崩溃(不是我的代码)
【发布时间】:2015-03-27 17:24:12
【问题描述】:

我从客户那里得到了下面的堆栈跟踪报告。我不知道如何重现这个。我的 WPF 应用程序有相当数量的组合框;鉴于下面的堆栈跟踪,我不确定如何确定哪个 ComboBox 失败。有没有其他人看过这个?你能从这个堆栈跟踪中解释发生了什么吗?有什么想法吗?

System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Windows.Controls.ComboBox.CoerceIsSelectionBoxHighlighted(Object o, Object value)
   at System.Windows.DependencyObject.ProcessCoerceValue(DependencyProperty dp, PropertyMetadata metadata, EntryIndex& entryIndex, Int32& targetIndex, EffectiveValueEntry& newEntry, EffectiveValueEntry& oldEntry, Object& oldValue, Object baseValue, Object controlValue, CoerceValueCallback coerceValueCallback, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, Boolean skipBaseValueChecks)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.DependencyObject.CoerceValue(DependencyProperty dp)
   at System.Windows.Controls.ComboBox.OnIsKeyboardFocusWithinChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.FocusWithinProperty.FireNotifications(UIElement uie, ContentElement ce, UIElement3D uie3D, Boolean oldValue)
   at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   at System.Windows.ReverseInheritProperty.OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, IList`1 otherOrigins, DeferredElementTreeState& oldTreeState, Action`2 originChangedAction)
   at System.Windows.Input.KeyboardDevice.ChangeFocus(DependencyObject focus, Int32 timestamp)
   at System.Windows.Input.KeyboardDevice.PostProcessInput(Object sender, ProcessInputEventArgs e)
   at System.Windows.Input.InputManager.RaiseProcessInputEventHandlers(ProcessInputEventHandler postProcessInput, ProcessInputEventArgs processInputEventArgs)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawKeyboardActions actions, Int32 scanCode, Boolean isExtendedKey, Boolean isSystemKey, Int32 virtualKey)
   at System.Windows.Interop.HwndKeyboardInputProvider.PossiblyDeactivate(IntPtr hwndFocus)
   at System.Windows.Interop.HwndKeyboardInputProvider.FilterMessage(IntPtr hwnd, WindowMessage message, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

【问题讨论】:

  • 对于它的价值,我今天遇到了同样的问题并设法解决了它。我在我的组合框上使用了SetWidthFromItems。如果我在不调用 SetWidthFromItems 的情况下清除了列表并添加了新项目,那么我会收到此错误。如果我在添加元素后调用 SetWidthFromItems,则不再发生错误。

标签: c# wpf combobox stack-trace


【解决方案1】:

这是代码 (.NET 4.5.2)。 o 不是 ComboBoxHighlightedElement 为空。

就我个人而言,我的第一步是分发 PDB,以便您可以在堆栈跟踪中获取行号。

private static object CoerceIsSelectionBoxHighlighted(object o, object value)
{
    ComboBox comboBox = (ComboBox)o;
    return (!comboBox.IsDropDownOpen && comboBox.IsKeyboardFocusWithin) ||
           (comboBox.HighlightedInfo != null && comboBox.HighlightedElement.Content == comboBox._clonedElement);
}

private ComboBoxItem HighlightedElement
{
    get { return (_highlightedInfo == null) ? null : _highlightedInfo.Container as ComboBoxItem; }
}

【讨论】:

  • @MyCodeSucks 抛出异常的方法。看看他的堆栈跟踪。
  • 那么他应该是发帖的人。它不属于答案。
  • 也许他没有,或者没见过?查看代码显示了可能的 null ref 异常可能来自何处。
  • 感谢您发布代码。这几乎看起来像是 WPF 源代码中的错字。他们应该检查 HighlightedElement 是否为 null 而不是 HighlightedInfo
  • 连接问题表明修复将在 4.6.2 版本中。 connect.microsoft.com/VisualStudio/feedback/details/1660886/…
【解决方案2】:

我们有一个定制的过滤组合框,我们将其作为继承自组合框的用户控件。在 Windows 10 机器上,我们开始在数据网格行上的表单中过滤组合框时出现此错误。我们在 DataGrid 上的 DataGrid.RowDetailsTemplate 中有一个过滤的组合框。

为了消除错误,我们在 Filtered_Combobox 类中覆盖了这个 sub。

Protected Overrides Sub OnIsKeyboardFocusWithinChanged(e As DependencyPropertyChangedEventArgs)
    Try


    Catch ex As Exception
    End Try
End Sub

注意:我们还没有在覆盖中添加任何代码,因为它似乎没有做任何事情(尽管应用程序崩溃)。

【讨论】:

    【解决方案3】:

    我们在运行时和窗口的某些(没有时间获得精确范围)版本上遇到了类似的问题。

    我们的一个组合框具有以下样式

    <ComboBox.Style>
        <Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
            <Setter Property="IsDropDownOpen" Value="False"/>
                <Style.Triggers>
                    <Trigger Property="IsKeyboardFocusWithin" Value="True">
                        <Setter Property="IsDropDownOpen" Value="True" />
                    </Trigger>
                </Style.Triggers>
        </Style>
    

    不知何故,有时会混淆选择突出显示并导致异常。 也许这会有所帮助。

    【讨论】:

      【解决方案4】:

      最终为我们解决这个问题的是覆盖导致问题的事件:

      Protected Overrides Sub OnIsKeyboardFocusWithinChanged(e As DependencyPropertyChangedEventArgs)
          Try
              'GW 2015-09-20 Added this override to prevent windows 10 crashes on comboboxes within forms within datagrids
      
          Catch ex As Exception
          End Try
      End Sub
      

      【讨论】:

        【解决方案5】:

        我遇到了与 maiksaray 共享的类似代码的相同错误。对我来说,CoerceIsSelectionBoxHighlighted 的 NullReferenceException 仅发生在 Windows 10 上,而不是在我的 Windows 7 开发机器上。仅在第一次单击打开组合框时发生。

        在我的例子中,我在加载视图时以编程方式打开和关闭组合框:

        public MyView()
        {
            InitializeComponent();
            Loaded += OnLoaded;
        }
        
        private void comboBox1_DropDownOpened(object sender, EventArgs e)
        {
            comboBox1.ItemsSource = MyClass.GetComboBoxList();
        }
        
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
           comboBox1.IsDropDownOpen = true;
           comboBox1.IsDropDownOpen = false;
        }
        

        我这样做是为了解决另一个问题,如下所述: http://blog.elgaard.com/2009/09/03/wpf-making-combo-box-items-disabled-also-when-accessed-using-the-keyboard/

        DevicesComboBox_DropDownOpened 完成后发生错误。但是,它只发生在 OnLoaded 代码存在的情况下。如果我注释掉 Loaded += OnLoaded,那么我没有收到错误消息。

        我的解决方案是简单地避免以编程方式打开和关闭 ComboBox。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-06-17
          • 2011-11-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-03
          相关资源
          最近更新 更多