-->

Numerical string sorting in a listbox

2019-03-02 02:43发布

问题:

I have a ListBox which ItemSource is bound to a CollectionViewSource. The CVS Source is an XmlDataProvider. So the ListBox lists all nodes (name attribute) i specified. Now those nodes have attributes, and i want the ListBox to be sorted by them. The problem is, since the underlying data is xml, every value(attributes of the node) is a string, but some of the values represent numerical values. Since sorting with CollectionViewSource.SortDescriptions.add (...) will sort those (string)values alphabetically, a sequence of 2,10,5 will be sorted as 10,2,5 instead of 2,5,10. How can i solve this?

If the solution lies in the ListView's CustomSort, could someone please provide me a quick example on how to to this with underlying XmlDocument?

I thought it would be as easy as writing a class which implements IComparer, but somehow i am lost. I wanted to pass the name of the attribute to the method, so i could just "extract" all those attributes from the CVS, convert them to float (in this case) and sort them with standard functions... But i am totally lost on how this CustomSort works to be honest....

Hope this is possible without ditching the XmlDocument, because it is kind of a given :)

Regards

回答1:

If you are binding to a collection that inherits from IList, you can retrieve a ListCollectionView from the ItemsSource property of your ListView control. Once you have an instance of a ListCollectionView, you can assign a sorting method to the CustomSorter property.

The custom sorter must inherit from the old style, non-generic IComparer. Within the Compare method, you get two instances of the bound class. You can cast those as needed to get your desired result. During development, you can anchor the debugger inside the Compare method to determine exactly what the objects are.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        List<string> strings = new List<string>() { "3", "2", "10", "1" };
        lv1.ItemsSource = strings;
        ListCollectionView lcv = 
             CollectionViewSource.GetDefaultView(lv1.ItemsSource) as ListCollectionView;
        if(lcv!=null)
        {
            lcv.CustomSort = new MySorter();
        }
    }
}
public class MySorter : IComparer
{
    public int Compare(object x, object y)
    { // set break point here!
        return Convert.ToInt32(x) - Convert.ToInt32(y);
    }
}