2013-01-16 18 views
7

Mam datagram danych wpf związany z atrybutem TrackableCollection. W rzadkich przypadkach i tylko dla kilku wybranych użytkowników aplikacja ulegnie awarii, gdy użytkownik doda nowy rekord, wprowadzając dolny pusty wiersz. Nie udało się odtworzyć problemu, a wszystko, co mam, to stos wyjątku. Czy ktoś widział coś takiego? Mam ograniczoną wiedzę na temat klas automatyzacji, ale mogę potwierdzić, że nie używamy żadnego z nich w naszej aplikacji.WPG DataGrid, awaria aplikacji podczas dodawania wiersza

Oto StackTrace:

System.ArgumentNullException: Value cannot be null. 
Parameter name: item 
    at System.Windows.Automation.Peers.DataGridAutomationPeer.CreateItemAutomationPeer(Object item) 
    at System.Windows.Automation.Peers.ItemsControlAutomationPeer.FindOrCreateItemAutomationPeer(Object item) 
    at System.Windows.Automation.Peers.DataGridAutomationPeer.RaiseAutomationSelectionEvents(SelectionChangedEventArgs e) 
    at System.Windows.Controls.DataGrid.OnSelectionChanged(SelectionChangedEventArgs e) 
    at System.Windows.Controls.Primitives.Selector.SelectionChanger.End() 
    at System.Windows.Controls.DataGrid.MakeFullRowSelection(Object dataItem, Boolean allowsExtendSelect, Boolean allowsMinimalSelect) 
    at System.Windows.Controls.DataGrid.HandleSelectionForCellInput(DataGridCell cell, Boolean startDragging, Boolean allowsExtendSelect, Boolean allowsMinimalSelect) 
    at System.Windows.Controls.DataGridCell.OnAnyMouseLeftButtonDown(MouseButtonEventArgs e) 
    at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) 
    at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) 
    at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent) 
    at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) 
    at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) 
    at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) 
    at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) 
    at System.Windows.Input.InputManager.ProcessStagingArea() 
    at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) 
    at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) 
    at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, 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 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) 

XAML:

<DataGrid Name="OrdreSLinjeGrid" 
      AutoGenerateColumns="False" 
      CanUserResizeRows="False" 
      CanUserAddRows="{Binding KanLeggeTilOrdreLinjer}" 
      HorizontalScrollBarVisibility="Disabled" 
      VerticalScrollBarVisibility="Visible" 
      ItemsSource="{Binding Order.OrderLines, Mode=TwoWay}" CanUserSortColumns="False" 
      SelectedItem="{Binding ValgtOrdreLinje}" > 
    <DataGrid.Columns>   
     <DataGridTextColumn 
      Header="{t:Translate Antall}" 
      TextAlignment="Right" 
      Width="50" 
      HeaderStyle="{StaticResource HøyrejustertColumnHeader}" 
      Binding="{Binding Antall, UpdateSourceTrigger=LostFocus}" /> 

     <DataGridTextColumn 
      Header="{t:Translate Pris}" 
      Width="60" 
      HeaderStyle="{StaticResource HøyrejustertColumnHeader}" 
      Binding="{Binding Pris, UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True}" 
      /> 
    </DataGrid.Columns> 
</DataGrid> 

Każde wejście lub sugestie będą mile widziane.

+2

Czy możesz również umieścić kod wokół tej logiki, w której występuje ten wyjątek? – ryadavilli

+0

Czy sieć jest przypisana do konkretnej nieruchomości? Jak wygląda twój Xaml? Co oznacza właściwość powiązana z xaml? –

+0

@ryadavilli Wyjątek nie występuje w naszym kodzie. To coś wewnętrznie w WPG DataGrid. –

Odpowiedz

1

Chciałbym sprawdzić zerowe wartości właściwości w modelu widoku. Jeśli właściwość ma wartość NULL, zastąp wartość pustą prawidłową wartością, np. 0 lub pustą.

Można to również zrobić za pomocą konwertera wartości

0

Mam ten sam problem. Występuje on w Datagrid, gdy użytkownik dwukrotnie kliknie pierwszy wiersz w DataGrid (tylko jeden wiersz). Dzieje się tak tylko na laptopie Sony z ekranem dotykowym. Oprogramowanie Sony dodaje pola wyboru do każdego pliku w Eksploratorze Winfows. Myślę, że ten problem jest związany z oprogramowaniem Sony.

1

Miałem ten sam problem z ekranem dotykowym. Posiadałem aplikację WPF, która działała bez zarzutu, dopóki nie połączyłem ekranu dotykowego, na którym zbudowano aplikację.

Ten problem występuje, gdy element wybrany DataGrid został ograniczony do obiektu, który był pusty;

postanowiłem to w ten sposób:

DataGrid Xaml miał ten wiersz:

SelectedItem="{Binding SelItem}" 

XVVM wyglądało:

public MyViewModel SelItem 
{ 

    get 
    { 
     if (m_selected == null) 
      return new MyViewModel(); 
     else 
      return m_selected; 
    } 
} 
8

problem dotyczy błędu w DataGridAutomationPeer.RaiseAutomationSelectionEvents wewnętrznym metoda, która po prostu nie sprawdza, czy właściwość SelectedItem ma wartość null, czy nie. Można go łatwo odtworzyć, uruchamiając narzędzie "Microsoft Narrator" w systemie Windows 7.

Ponieważ jest to klasa zamknięta, nie ma prostego sposobu na jej naprawę, z wyjątkiem przechwytywania tej metody za pomocą narzędzia Reflection.Emit lub dowolnego narzędzia szyderczego, a nawet jeśli zostanie naprawiony, nie mamy gwarancji, że Microsoft nie zmieni nazwy, podpisu lub zachowania tej metody.

Zaimplementowałem poprawkę "wystarczająco dobrą", dziedzicząc z DataGrid, która zmieni sposób odznaczenia DataGrid, gdy SelectedItem ma wartość null, ale tylko wtedy, gdy narrator/ekran dotykowy jest obecny.

Mam nadzieję, że błąd zostanie wkrótce naprawiony. W razie potrzeby dodaj odwołanie do UIAutomationProvider.

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

Dobre rozwiązanie, dzięki! –

2

Wiem, że jest dość stary, ale istnieje dobre rozwiązanie tego problemu, z którym się zetknąłem.Można zdefiniować niestandardową konwertera za pomocą interfejsu IValueConverter:

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; 
    } 
} 

Sprawdza, czy wartość jest null a jeżeli tak, to zwraca DependecyProperty.UnsetValue. Jak opisano w documentation (spojrzeć na opisy metoda):

Wartość powrót DependencyProperty.UnsetValue wskazuje, że przetwornica produkowane żadnej wartości i że wiązania wykorzystuje FallbackValue, jeśli są dostępne, lub wartość domyślna zamiast.

Powrocie tego zamiast null powinien rozwiązać problem.

+0

w napisanej przez ciebie metodzie 'Zwróć' Zwróć wartość! = Null? DependencyObject.UnsetValue: value', nie powinno to być: 'return value == null? DependencyObject.UnsetValue: value' – Formentz

+1

Dobra uwaga, zmienię to – yinnonsanders

Powiązane problemy