Wpf DataGridComboBox - exception thrown when binding to a navigator of an entity while sorting

Posts   
 
    
scaless
User
Posts: 22
Joined: 28-Mar-2011
# Posted on: 24-Aug-2011 22:01:58   

LLBLGen Pro V: 3.1 Final Runtime Library V: 3.1.11.318 .NET Version: 4.0 Template Group: Both Adapter **Oracle V: **10g Oracle Clieng V: 11.1 Inheritance Hierarchies: None **OPD Oracle.DataAccess.dll **V: 2.111.7.20

Hello,

I am running into an issue when I try to sort a DataGrid by a column populated by a Navigator of an entity. The exception tells me the following:

ShpYearEntityCollection' type does not have property named 'ShpYearLevel.Description', so cannot sort data collection.

The ShpYearLevel.Description comes from the DataGridComboBox's SortMemberPath property. The ShpYearLevel property is a Navigator property for the ShpYear class.

Here is simplified xaml code for the data grid which still procedures the exception:


        <DataGrid Grid.Row="1"
                  Margin="5"
                  CanUserAddRows="False"
                  CanUserDeleteRows="False"
                  AutoGenerateColumns="False"
                  ItemsSource="{Binding Path=EmployerEntity.ShpYears}"
                  SelectedValue="{Binding Path=SelectedYear}"
                  SelectionChanged="DataGrid_SelectionChanged"
                  x:Name="grid">
            <DataGrid.Columns>
                <DataGridComboBoxColumn Header="Year"
                                        ItemsSource="{Binding Source={StaticResource viewModel}, Path=YearLevelCollection}"
                                        DisplayMemberPath="Description"
                                        SortMemberPath="ShpYearLevel.Description"
                                        SelectedValueBinding="{Binding Path=ShpYearLevel}" 
                                        x:Name="col"/>
                <DataGridTextColumn Header="Tk"
                                    Binding="{Binding Path=Tk}" />
            </DataGrid.Columns>
        </DataGrid>

In the above code the DataContext of the grid that contains the DataGrid is set to the view model, which is a static resource.

Here is the view model class I am using:


    class ViewModel : INotifyPropertyChanged
    {
        public ViewModel()
        {
        }

        public void InitializeViewModel()
        {
            GetEmployer();
        }

        private ShpEmployerEntity _employerEntity;
        private ShpYearEntity _selectedYear;
        private EntityCollection<ShpYearLevelEntity> _yearLevelCollection;

        private void GetEmployer()
        {

            EmployerEntity = new ShpEmployerEntity(4);
            var prefetch = new PrefetchPath2((int)EntityType.ShpEmployerEntity);
            var sorter = new SortExpression(ShpYearFields.ApprovalDate | SortOperator.Descending);
            var elementYr = prefetch.Add(ShpEmployerEntity.PrefetchPathShpYears, 0, null, null, sorter);
            var elementYr2 = elementYr.SubPath.Add(ShpYearEntity.PrefetchPathShpYearLevel);

            string connString = ConfigurationManager.ConnectionStrings["oracle"].ConnectionString;

            YearLevelCollection = new EntityCollection<ShpYearLevelEntity>();

            using (var adapter = new DataAccessAdapter(connString))
            {
                adapter.FetchEntity(EmployerEntity, prefetch);
                OnPropertyChanged("EmployerEntity");

                adapter.FetchEntityCollection(YearLevelCollection, null);
            }

            SelectedYear = EmployerEntity.ShpYears[0];
        }

        public EntityCollection<ShpYearLevelEntity> YearLevelCollection
        {
            get { return _yearLevelCollection; }
            set { _yearLevelCollection = value; OnPropertyChanged("YearLevelCollection"); }
        }

        public ShpYearEntity SelectedYear
        {
            get { return _selectedYear; }
            set { _selectedYear = value; OnPropertyChanged("SelectedYear"); }
        }

        public ShpEmployerEntity EmployerEntity
        {
            get { return _employerEntity; }
            set { _employerEntity = value; OnPropertyChanged("EmployerEntity"); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

The above view model code is also simplified code to help drill down to the issue without the full application code getting in the way. The InitializeViewModel call populates the EmployerEntity property, which contains the navigator EntityCollection<ShpYearEntity> ShpYears, which is the ItemsSource for the DataGrid.

One thing to note. I tried to replicate this with a simple class and manually populated collection of that class type. The class had a property, which was another class simulating a navigator in this case. The sorting function of the data grid worked in that case. Here is the xaml code for that data grid:


        <DataGrid AutoGenerateColumns="False"
                  ItemsSource="{Binding Path=Entities}"
                  SelectedValue="{Binding Path=SelectedEntity}"
                  CanUserAddRows="False"
                  CanUserDeleteRows="False"
                  Margin="5">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Tk"
                                    Binding="{Binding Path=Tk}" />
                <DataGridTextColumn Header="Description"
                                    Binding="{Binding Description}" />
                <DataGridComboBoxColumn Header="Is Active"
                                        ItemsSource="{Binding Path=ActiveTypes, Source={StaticResource viewModel}}"
                                        SortMemberPath="IsEntityActive.Description"
                                        SelectedValueBinding="{Binding Path=IsEntityActive, Mode=TwoWay}"
                                        DisplayMemberPath="Description"/>
            </DataGrid.Columns>
        </DataGrid>

Any help would be appreciated.

Thanks, Shaun

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 25-Aug-2011 05:00:28   

Hi Shaun,

WPF can't find the realtedentity.property. So try to add a custom property in your ShpYearEntity (partial class):

public partial class ShpYearEntity
{
     public string Description
    {
          string toReturn = string.Empty;
          if (ShpYearLevel != null)
          {
                toReturn = ShpYearLevel.Description;
          }
    }
}

Then use that property in your grid:

<DataGrid Grid.Row="1"
                 Margin="5"
                 CanUserAddRows="False"
                 CanUserDeleteRows="False"
                 AutoGenerateColumns="False"
                 ItemsSource="{Binding Path=EmployerEntity.ShpYears}"
                 SelectedValue="{Binding Path=SelectedYear}"
                 SelectionChanged="DataGrid_SelectionChanged"
                 x:Name="grid">
            <DataGrid.Columns>
                <DataGridComboBoxColumn Header="Year"
                                        ItemsSource="{Binding Source={StaticResource viewModel}, Path=YearLevelCollection}"
                                        DisplayMemberPath="Description"
                                        SortMemberPath="Description"
                                        SelectedValueBinding="{Binding Path=ShpYearLevel}" 
                                        x:Name="col"/>
                <DataGridTextColumn Header="Tk"
                                    Binding="{Binding Path=Tk}" />
            </DataGrid.Columns>
        </DataGrid>
David Elizondo | LLBLGen Support Team
scaless
User
Posts: 22
Joined: 28-Mar-2011
# Posted on: 26-Aug-2011 20:29:06   

This worked. Thanks.

-Shaun