views:

27

answers:

1

Hi,

I am binding my WPF Datagrid to an XML source. I have a DataGridTextColumn column representing the Id of my object. When I sort on that column, it gives me for example: 1, 12, 13, 2, 3, 31, 4.

I obviously would like to sort it as 1, 2, 3, 4, 12, 13, 31.

Is there a way to specify that I want to sort the column based on the integer representation of the string?

Thanks.

A: 

You will need to do the sorting yourself. You can use linq to easily sort xml. Below sample sorts numbers as you expect when clicking on headers. I only implemented ascending sort.

XAML:

<Window x:Class="DataGridDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Controls="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
    Height="300" Width="300">
    <StackPanel>
        <Controls:DataGrid 
            ItemsSource="{Binding Path=Trades}"
            Sorting="OnSorting">
            <Controls:DataGrid.Columns>
                <Controls:DataGridTextColumn Header="Side" Binding="{Binding Path=Attribute[Side].Value}" />
                <Controls:DataGridTextColumn Header="Price" Binding="{Binding Path=Attribute[Price].Value}" />
                <Controls:DataGridTextColumn Header="Volume" Binding="{Binding Path=Attribute[Volume].Value}" />
            </Controls:DataGrid.Columns>
        </Controls:DataGrid>
    </StackPanel>
</Window>

Code behind:

using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Xml.Linq;
using Microsoft.Windows.Controls;

namespace DataGridDemo
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            DataContext = new VM();
        }

        private void OnSorting(object sender, DataGridSortingEventArgs e)
        {
            e.Handled = true;

            (DataContext as VM).SortCol = e.Column.Header as string;
        }
    }

    public class VM : INotifyPropertyChanged
    {
        public VM()
        {
            _data = 
                new XElement("Trades",
                             new XElement("Trade", new XAttribute("Side", "Buy"), new XAttribute("Price", "3.23"), new XAttribute("Volume", "100")),
                             new XElement("Trade", new XAttribute("Side", "Sell"), new XAttribute("Price", "13.12"), new XAttribute("Volume", "200")),
                             new XElement("Trade", new XAttribute("Side", "Buy"), new XAttribute("Price", "04.1"), new XAttribute("Volume", "15")),
                             new XElement("Trade", new XAttribute("Side", "Buy"), new XAttribute("Price", "30.78"), new XAttribute("Volume", "120")));

            SortCol = "Price";
        }

        private string _sortCol;
        public string SortCol
        {
            get { return _sortCol; }
            set
            {
                _sortCol = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(""));
                }
            }
        }

        public IEnumerable<XElement> Trades
        {
            get
            {
                if (SortCol == "Side")
                {
                    return from trade in _data.Elements("Trade")
                        orderby (string)trade.Attribute(SortCol)
                        select trade;
                }

                return
                    from trade in _data.Elements("Trade")
                    orderby (double)trade.Attribute(SortCol)
                    select trade;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private XElement _data;
    }
}
Wallstreet Programmer
Thanks, I also found another way of doing it: http://blogs.msdn.com/b/jgoldb/archive/2008/08/26/improving-microsoft-datagrid-ctp-sorting-performance.aspx
joerage