WPF DataGrid, application crash when adding a row

前端 未结 6 1672
青春惊慌失措
青春惊慌失措 2021-02-08 02:29

I have a wpf datagrid bound to a TrackableCollection. In some rare occations, and for only a few selected users, the application will crash when the user adds a new record by en

相关标签:
6条回答
  • 2021-02-08 02:46

    The problem is related to a bug in DataGridAutomationPeer.RaiseAutomationSelectionEvents internal method which simply speaking does not check if SelectedItem property is null or not. It can easily be reproduced by running "Microsoft Narrator" tool in Windows 7.

    Because this is a sealed class there is no easy way to fix it except intercepting this method using Reflection.Emit or any mocking tool out there and even if it's fixed we have no guarantee that Microsoft won't change this method name, signature or behaviour.

    I implemented a "good enough" fix by inheriting from DataGrid which will change the way DataGrid is unselected when the SelectedItem is null but only if narrator/touchscreen is present.

    Hopefully the bug will be fixed soon. Add reference to UIAutomationProvider if necessary.

    using System.Windows.Automation.Peers;
    using System.Windows.Controls;
    
    public class TooDataGrid: DataGrid
    {
        protected override void OnSelectionChanged(SelectionChangedEventArgs e)
        {
            if(AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementSelected) ||
                AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementAddedToSelection) ||
                AutomationPeer.ListenerExists(AutomationEvents.SelectionItemPatternOnElementRemovedFromSelection))
            {
                if(SelectedItem == null)
                {
                    return;
                }
            }
            base.OnSelectionChanged(e);
        }
    }
    
    0 讨论(0)
  • 2021-02-08 02:51

    I have the same issue. It occurs on Datagrid when user double clicks first row in DataGrid (with only one row). This is occurs only on Sony laptop with touchscreen. Sony software adds checkboxes to every file in Winfows Explorer. I think this problem is related to the sony software.

    0 讨论(0)
  • 2021-02-08 02:53

    No need for converters or for using a derived class. Just make sure that the property you are binding to for SelectedItem is initialized with DependencyProperty.UnsetValue. Do not set it to or leave it at the default of null.

    The underlying bug should be fixed in the not-too-far future, btw: https://developercommunity.visualstudio.com/content/problem/575165/vs-1604-ide-crash-argumentnullexception.html

    0 讨论(0)
  • 2021-02-08 02:55

    I would try to check for nulls on your properties in your view model. If the property is null, replace the null with a valid value like a 0 or a blank.

    You could also do this using a Value Converter

    0 讨论(0)
  • 2021-02-08 02:56

    I know this is pretty old, but there is a good solution to this problem that I came across. You can define a custom converter using the IValueConverter interface:

    public class SelectedItemConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value ?? DependencyProperty.UnsetValue;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (value == null || value.GetType().Name == "NamedObject") ? null : value;
        }
    }
    

    This checks if the value is null and if it is, returns DependecyProperty.UnsetValue. As described in the documentation (look at the method descriptions):

    A return value of DependencyProperty.UnsetValue indicates that the converter produced no value and that the binding uses the FallbackValue, if available, or the default value instead.

    Returning this rather than null should fix the issue.

    0 讨论(0)
  • 2021-02-08 03:00

    I had the same issue with touch screen only. I had a WPF app that was working fine until I connected the touch screen that the app was built for.

    This issue occur when the DataGrid selected item was bounded to an object that was null;

    I resolved it this way:

    The DataGrid Xaml had this line:

    SelectedItem="{Binding SelItem}"
    

    The XVVM looked like:

    public MyViewModel SelItem
    {
    
        get
        {
            if (m_selected == null)
                 return new MyViewModel();
            else
                 return m_selected;
        }
    }
    
    0 讨论(0)
提交回复
热议问题