2013-01-16 2 views
7

У меня есть wpf datagrid, связанный с TrackableCollection. В некоторых редких случаях и только для нескольких избранных пользователей приложение будет разбиваться, когда пользователь добавит новую запись, введя нижнюю пустую строку. Я не смог воспроизвести проблему, и все, что у меня есть, - это стек из созданного исключения. Кто-нибудь видел что-нибудь подобное? У меня ограниченные знания о классах автоматизации, но я могу подтвердить, что мы не используем ни одно из них в нашем приложении.WPF DataGrid, сбой приложения при добавлении строки

Вот 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> 

Любой вход или предложения будут оценены.

+2

Можете ли вы также опубликовать код вокруг этой логики, где происходит это исключение? – ryadavilli

+0

Связана ли ваша сетка с определенным свойством? Как выглядит ваш xaml? Что свойство, связанное с xaml? –

+0

@ryadavilli Исключение не происходит в нашем коде. Это что-то внутренне в WPF DataGrid. –

ответ

1

Я бы постарался проверить наличие нулей в ваших свойствах в вашей модели. Если свойство равно null, замените значение null допустимым значением, равным 0 или пробелу.

Вы также можете сделать это, используя значение конвертер

0

У меня есть один и тот же вопрос. Это происходит в Datagrid, когда пользователь дважды щелкает первую строку в DataGrid (только с одной строкой). Это происходит только на ноутбуке Sony с сенсорным экраном. Программное обеспечение Sony добавляет флажки в каждый файл в Winfows Explorer. Я думаю, эта проблема связана с программным обеспечением sony.

1

У меня была та же проблема только с сенсорным экраном. У меня было приложение WPF, которое отлично работало, пока я не подключил сенсорный экран, для которого было создано приложение.

Эта проблема возникает, когда выбранный элемент DataGrid был ограничен объектом, который был нулевым;

Я решил это так:

DataGrid Xaml имел следующую строку:

SelectedItem="{Binding SelItem}" 

XVVM выглядел как:

public MyViewModel SelItem 
{ 

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

Проблема связана с ошибкой в ​​DataGridAutomationPeer.RaiseAutomationSelectionEvents внутренней метод, который просто не проверяет, является ли свойство SelectedItem нулевым или нет. Его можно легко воспроизвести, запустив инструмент «Microsoft-рассказчик» в Windows 7.

Поскольку это запечатанный класс, нет простого способа его исправить, кроме перехвата этого метода с использованием Reflection.Emit или любого из насмехающего инструмента там и даже если он исправлен, мы не гарантируем, что Microsoft не изменит это имя метода, подпись или поведение.

Я реализовал исправление «достаточно хорошо», наследуя от DataGrid, который изменит способ, которым DataGrid не выбран, когда SelectedItem имеет значение NULL, но только если присутствует рассказчик/сенсорный экран.

Надеюсь, ошибка будет исправлена ​​в ближайшее время. При необходимости добавьте ссылку на 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

Хорошее решение, спасибо! –

2

Я знаю, что это довольно старый, но есть хорошее решение этой проблемы, с которой я столкнулся.Вы можете определить пользовательский преобразователь с помощью интерфейса 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; 
    } 
} 

Это проверяет, является ли значение null и если она возвращает DependecyProperty.UnsetValue. Как описано в documentation (смотрите на описание метода):

Возвращаемое значение указывает на то, что DependencyProperty.UnsetValue преобразователь не производится никакого значения и что связывание использует FallbackValue, если таковые имеются, или значение по умолчанию, вместо этого.

Возврат этого, а не null должен устранить проблему.

+0

в методе 'Convert', который вы написали' return value! = Null? DependencyObject.UnsetValue: значение ', не должно быть:' return value == null? DependencyObject.UnsetValue: value' – Formentz

+1

Хорошо, я переключу это – yinnonsanders

Смежные вопросы