WPF Datagrid Crashes On Header Sort

2

This Question is related to What is it about DataTable Column Names with dots that makes them unsuitable for WPF's DataGrid control?.

I'm using a datagrid to show results for an ad hoc query builder, so the datatable columns can be anything.

I followed the answer with the most votes (14). everything worked great but if I click on the header to sort the column the whole application crashes.

Error:

System.IndexOutOfRangeException   HResult=0x80131508   Message=Index was outside the bounds of the array.   Source=AppName   StackTrace:    at AppName.App.ShowUnhandeledException(DispatcherUnhandledExceptionEventArgs e) in <path>\App.xaml.cs:line 51    at AppName.App.AppDispatcherUnhandledException(Object sender, DispatcherUnhandledExceptionEventArgs e) in <path>\App.xaml.cs:line 27 at System.Windows.Threading.Dispatcher.CatchException(Exception e)    at System.Windows.Threading.Dispatcher.CatchExceptionStatic(Object source, Exception e)    at System.Windows.Threading.ExceptionWrapper.CatchException(Object source, Exception e, Delegate catchHandler)    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)  at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)    at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)    at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)    at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)    at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)   at System.Windows.Application.RunDispatcher(Object ignore)    at System.Windows.Application.RunInternal(Window window)    at System.Windows.Application.Run(Window window)    at System.Windows.Application.Run()    at AppName.App.Main()

This is my XAML:

<DataGrid x:Name="DgridQueryResults" Grid.Row="1" Background="LightGray" Margin="5" ItemsSource ="{Binding .}" IsReadOnly="True" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeColumns="true" CanUserReorderColumns="False" CanUserSortColumns="True" ClipboardCopyMode="ExcludeHeader"SelectionUnit="Cell" CopyingRowClipboardContent="DgridQueryResults_CopyingRowClipboardContent" Grid.ColumnSpan="2"/>                             

I tried the above where item source is like ItemsSource ="{Binding}" but it still crashes.

I add brackets programmatically as follows:

        private void DgridQueryResults_ColumnSetup()
    {
        DgridQueryResults.Columns.Clear();
        DgridQueryResults.AutoGenerateColumns = false;
        foreach (DataColumn column in _results.Columns)
        {
            var gridColumn = new DataGridTextColumn()
            {
                Header = column.ColumnName,
                Binding = new Binding("[" + column.ColumnName + "]")
            };

            DgridQueryResults.Columns.Add(gridColumn);
        }
    }

I setup the columns before setting the item source as follows:

        private void ExecuteSql()
    {
        if (_dataFormData.GetDataViaReader(_sql))
        {
            _results = _dataFormData.DT;
            DgridQueryResults_ColumnSetup();// <-- column setup
            DgridQueryResults.DataContext = _results.DefaultView;

        }
        else
        {
            DgridQueryResults.DataContext = null;
        }

        QueryResults.Focus();
    }

Commenting out column setup works fine, but then I can't have column names that violate binding (i.e., full stop (.)).

Also setting setting user sort to false in XAML fixes it but then, of course, the user can't sort the data.

I'm using VS 2017 15.5.1 against Framework 4.6.1.

Is anybody else experiencing this? I appreciate any help. Thank you!

c#
wpf
binding
datagrid
asked on Stack Overflow Dec 13, 2017 by Gapster • edited Dec 13, 2017 by Gapster

1 Answer

2

I figured it out. I had to add the sort member path when adding the columns.

private void DgridQueryResults_ColumnSetup()
{
    DgridQueryResults.Columns.Clear();
    DgridQueryResults.AutoGenerateColumns = false;
    foreach (DataColumn column in _results.Columns)
    {
        var gridColumn = new DataGridTextColumn()
        {
            Header = column.ColumnName,
            SortMemberPath = column.ColumnName, //<--added
            Binding = new Binding("[" + column.ColumnName + "]")
        };


        DgridQueryResults.Columns.Add(gridColumn);
    }
}
answered on Stack Overflow Dec 13, 2017 by Gapster

User contributions licensed under CC BY-SA 3.0