none
How To Resolve WPF DataGrid Binding Errors: System.Windows.Data Error: 40 : BindingExpression path error

    Question

  • Greetings;


    I'm having difficulty using WPF's support for Data Binding a generic List<> instance to a Read-Only DataGrid inside a Window.  To setup the Data Binding, I have the following in place in the code:

    1.) I set the Window's DataContext to a reference type of FormattedStackTrace exposed as a public property named StackTrace.  The DataContext is set in the Window's class constructor in C# as follows:

            public CallStackDialog(Window owner,
                   FormattedStackTrace stackTrace)
            {
                InitializeComponent();
                this.Owner = owner;
    
                StackTrace = stackTrace;
                DataContext = StackTrace;
    
                return;
            }

    The instance of StackTrace is non-null, and I can access and view all of its property members through the StackTrace property as expected.  Likewise, the Window's DataContext is a non-null value.

    2.) The StackTrace property is implemented in the same window class as follows:

            private FormattedStackTrace formattedStackTrace;
    
            public FormattedStackTrace StackTrace
            {
                get
                {
                    return formattedStackTrace;
                }
    
                set
                {
                    formattedStackTrace = value;
                    NotifyPropertyChanged("StackTrace");
                }
            }
    
    3.) The FormattedStackTrace class contains an instance of List<OrderedCall> as an auto property named OrderedStackTrace.  I am trying to bind this collection as the ItemsSource for the DataGrid in the window. The relative members of the FormattedStackTrace, which is the backing reference type for the Window's DataContext, is as follows:
        public class FormattedStackTrace
        {
    #region FormattedStackTrace Class Data Members & Auto-Properties
    
            private StackFrame[] sourceStackFrame;
            public MethodBase CallingMethod { get; private set; }
            public List<OrderedCall> OrderedStackTrace { get; private set; }
    
    #endregion
        }
    
    OrderedStackTrace is a List<OrderedCall>, where each List member is an instance of the following structure:
        public struct OrderedCall
        {
            public int Call;
            public string Method;
        }; 
    
    At the point where the DataContext is set inside the parent Window's class constructor, the OrderedStackTrace property is correct, in that it contains the expected number of OrderedCall instance values, and they can be viewed without issue inside any of the Debugging tabs inside Visual Studio 2010, or inside the IDE's Immediate Window:

        ? StackTrace.OrderedStackTrace == null
        false
        ? StackTrace.OrderedStackTrace.Count
        40
        ? StackTrace.OrderedStackTrace[39]
        {WPFEventHandling.OrderedCall}
            Call: 40
            Method: "WPFEventHandling.MainWindow.OnMousePointerEnteredButton(Object sender, MouseEventArgs e)"


    4.) The DataGrid inside the Window I'm trying to bind to, StackTraceDataGrid, which is read only, is implemented in XAML as follows:

    <DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" 
              Name="StackTraceDataGrid" IsReadOnly="True"
              AutoGenerateColumns="False" Margin="10" 
              ItemsSource="StackTrace.OrderedStackTrace">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Offest" 
             Binding="{Binding Call}" Width="60">
            </DataGridTextColumn>
            <DataGridTextColumn Header="Method" 
             Binding="{Binding Method}" Width="*">
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
    
    When I build the solution containing this Window and  the child StackTraceDataGrid control, there are no errors nor compiler warnings. When I bring up the parent window that contains StakTraceDataGrid, the DataGrid and the two Text Columns, Offset and Method, are rendered and formatted as expected, but each row in the DataGrid is empty.  When the Window is brought up, the following set of runtime messages appear for each pair of OrderedCall member values in each column for each row:

    System.Windows.Data Error: 40 : BindingExpression path error: 'Call' property not found on 'object' ''Char' (HashCode=7471218)'. BindingExpression:Path=Call; DataItem='Char' (HashCode=7471218); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Method' property not found on 'object' ''Char' (HashCode=7471218)'. BindingExpression:Path=Method; DataItem='Char' (HashCode=7471218); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

    As far as I can tell, I think that my problem may lie in how I've defined the ItemsSource property for the DataGrid, and the Binding Path for each column for each instance of OrderedCall as I would like to have displayed in each row of the Grid.

    I would really appreciate any corrections on how to resolve the BindingExpression path errors I'm seeing at runtime, as well as any background informatio on what each DataGrid Column is expecting for a Binding Path for each item in each row of the DataGrid.

    Thank you in advance for your time and help, and I look forward to hearing from you soon.


    Wednesday, August 29, 2012 3:08 AM

Answers

  • Change your struct like this

     public struct  OrderedCall
        {
            public int Call{get;set ;}
            public string Method{get; set;}
        }; 

    let me know if you still face any issue.
    • Marked as answer by ClockEndGooner Thursday, August 30, 2012 11:43 AM
    Thursday, August 30, 2012 7:39 AM

All replies

  • Hi

    Try ItemsSource="{Binding StackTrace.OrderedStackTrace}"

    instead of ItemsSource="StackTrace.OrderedStackTrace"

    Thursday, August 30, 2012 2:57 AM
  • Abhishek;

    Thank you for your time and suggestions; I really appreciate the help.

    I tried your suggestion on modifying the DataGrid ItemsSource value with your recommendation first, followed by a slight variation.  However, neither of the two approaches worked in populating the DataGrid as expected.

    With your suggestion on setting the ItemsSource value to "{Binding StackTrace.OrderedStackTrace}" as with:

    <DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" 
              Name="StackTraceDataGrid" IsReadOnly="True"
              AutoGenerateColumns="False" Margin="10" 
              ItemsSource="{Binding StackTrace.OrderedStackTrace}">
    ... the lines that delineate the rows and columns in the DataGrid are no longer drawn, there are no values displayed inside the grid, and the following runtime binding error message appears in the Output pane inside Visual Studio:

    System.Windows.Data Error: 40 : BindingExpression path error: 'OrderedStackTrace' property not found on 'object' ''String[]' (HashCode=25993264)'. BindingExpression:Path=StackTrace.OrderedStackTrace; DataItem='FormattedStackTrace' (HashCode=14505765); target element is 'DataGrid' (Name='StackTraceDataGrid'); target property is 'ItemsSource' (type 'IEnumerable')

    Alternatively, I tried specifying the ItemsSource using just "{Binding OrderedStackTrace}", since the StackTrace was set as the DataContext for the DataGrid's parent Window inside the Window's class constructor:
    <DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" 
              Name="StackTraceDataGrid" IsReadOnly="True"
              AutoGenerateColumns="False" Margin="10" 
              ItemsSource="{Binding OrderedStackTrace}">
    
    The lines that delineate the rows and columns in the DataGrid appear again, and with the grid contents empty again, the following runtime binding error message appears in the Output pane inside Visual Studio:

    System.Windows.Data Error: 40 : BindingExpression path error: 'Call' property not found on 'object' ''OrderedCall' (HashCode=1118531950)'. BindingExpression:Path=Call; DataItem='OrderedCall' (HashCode=1118531950); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Method' property not found on 'object' ''OrderedCall' (HashCode=1118531950)'. BindingExpression:Path=Method; DataItem='OrderedCall' (HashCode=1118531950); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

    As always, I'm open to any additional ideas or suggestions on how to resolve this issue.



    ClockEndGooner social.msdn.microsoft.com

    Thursday, August 30, 2012 3:34 AM
  • Change your struct like this

     public struct  OrderedCall
        {
            public int Call{get;set ;}
            public string Method{get; set;}
        }; 

    let me know if you still face any issue.
    • Marked as answer by ClockEndGooner Thursday, August 30, 2012 11:43 AM
    Thursday, August 30, 2012 7:39 AM
  • Abhishek;

    Truth be told, I was a bit skeptical about trying to change the OrderedCall structure member definitions to auto-properties; both were already public in scope as well as the structure itself.  But I'm glad I tried it, and even more grateful for your suggestion.  It worked!!!

    The OrderedCall struct is now defined as:

        public struct OrderedCall
        {
            public int Call { get; set; }
            public string Method { get; set; }
        };

    ... and the DataGrid in XAML is defined as;

    <DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
              Name="StackTraceDataGrid" IsReadOnly="True"
              AutoGenerateColumns="False" Margin="10" 
              ItemsSource="{Binding OrderedStackTrace}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Offest" 
             Binding="{Binding Call}" Width="60">
            </DataGridTextColumn>
            <DataGridTextColumn Header="Method" 
             Binding="{Binding Method}" Width="*">
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>

    ... with the definition for ItemsSource using just "{Binding OrderedStackTrace}" as the Window StackTrace property, which contains the OrderedStackTrace is already set as the Window's DataContext.

    Now I'm still currious why the struct auto-properties work, and not the version of the structure without auto-properties.  Does the WPF Binding runtime support only work with reference type property accesors and not structure members, even though their respective scope declarations are the same?  Any insights as to why this approach works would be greatly appreciated.

    Again, many, many thanks for your time, help and patience.

    ClockEndGooner social.msdn.microsoft.com

    Thursday, August 30, 2012 11:42 AM