views:

1064

answers:

3

I have WPF datagrid with combox column (ID is real value, Desc is displayed value) and when I click on header of that column automatically sorts by real value (ID). I want to sort by displayed value.

My WPF datagrid has 4 columns: IdPerson, DescSchool, IdSchool and School. Column "School" is comboBox with this values:ItemSource = schoolTable.DefaultView, SelectedValueBinding = new Binding("IdSchool"), SelectedValuePath="IDSchool", DisplayMemberPath = "DescSchool"

schoolTable is a table with 2 columns - IDSchool and DescSchool. That table is used just as datasource for combobox.

I tried the solution when I have set SortMemberPath = "DescSchool" and initially, this works - when I click on the header of the combobox column sorting is done by displayed value (because it read value of the other column) and not by real value. But, if I change the value of the combobox, value of the column "DescSchool" is still the same so after that sorting doesn't work anymore properly.

Any idea?

+1  A: 

Setting SortMemberPath="Desc" (or what your property is called) on the DataGridComboBoxColumn should do the trick.

Oskar
Thank you for your answer. I tried that and that solution does not work for me for the motives that I have explained in my edited initial post.
A: 

I have also had this problem and had to implement IComparable on the type that is being sorted. So in your case I think it is the School type. Inside IComparable, return this:

return this.Desc.CompareTo((obj as School).Desc);

This is the only way I was able to get this to work, and judging by the lack of responses, not many people know a better way...sorry.

Also, this will only work if you have access to the types. If this is a datatable or something like that (as opposed to Entity Framework for example) this solution will not work.

Mike Gates
A: 

I had similar problem to solve with WinForm and its DataGridView displaying relational data in a combobox column in the grid. Wanted to sort the column but the sorting would sort by the ValueMember (an int ID field) and not the DisplayMember (text field being displayed). I was using a typed dataset and put its typed table into a DataView and use that DataView as the Datasource for a BindingSource which was then the Datasource for the grid. :-)

After reading several posts on the web, the solution that worked for me was the following: In the code-behind of the Typed dataset, I added some custom properties to the Typed Row of my main typed table.

Example:

        public string ProvinceAtRow
        {
            get
            {
                string result = string.Empty;
                if (!this.CustomerInfoRow.IsProvinceDescriptionNull())
                {
                    result = this.CustomerInfoRow.ProvinceDescription;
                }
                return result;
            }
        }

Next in the code-behind of the WinForm that has an instance of my typed Dataset, I added a DataColumn to the typed table. Example (code in the Load event of the winForm):

        this.DSGrowth.LocalGrowthFactor.Columns.Add(
            new DataColumn("Province", typeof(string)));

Next when have data in the dataset, must fill in the column(s) that were added. Example:

            //if we have data then have to fill in the colums we added to the TDS
        if (this.DSGrowth.LocalGrowthFactor.Rows.Count > 0)
        {
            //fill columns so that can display on datagrid as columns that can be sorted
            // ref  http://www.daniweb.com/forums/thread283915.html
            Array.ForEach<dsLocalGrowthFactor.LocalGrowthFactorRow>(                    this.DSGrowth.LocalGrowthFactor.Rows.OfType<dsLocalGrowthFactor.LocalGrowthFactorRow>().ToArray(),
                row =>
                {
                    row["Province"] = row.ProvinceAtRow;
                }
            );

            //accept changes on TDS so not to be prompted to save changes
            this.DSGrowth.AcceptChanges();
        }

        //set default sort
        DataView dvFactors = new DataView(this.DSGrowth.LocalGrowthFactor);
        dvFactors.Sort = "GrowthFactor DESC";
        this.BSLocalGrowth.DataSource = dvFactors;

        this.DgvGrowth.DataSource = this.BSLocalGrowth;
        if (this.DgvGrowth.Rows.Count > 0)
        {
            //select first row
            this.BSLocalGrowth.MoveFirst();
            this.DgvGrowth.Rows[0].Selected = true; 
        }

No more ComboBox columns and sorting works!

Hope this helps all out there who are in similar situation.

sheir