How to make a Sortable ObservableCollection C#

Time ago i had to implement a sortable observable collection that was able to sort its members based on different parameters.
After long and long searching i found this code, and i report it here so it can be useful for readers too.
/*
/*
 * samples:
 * //sort ascending
 * MySortableList.Sort(x => x.Name, ListSortDirection.Ascending);
 *
 * //sort descending
 * MySortableList.Sort(x => x.Name, ListSortDirection.Descending);
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace TestSortableCollection
{
    public class SortableObservableCollection : ObservableCollection
    {
        public void Sort(Func keySelector, System.ComponentModel.ListSortDirection direction)
        {
            switch (direction)
            {
                case System.ComponentModel.ListSortDirection.Ascending:
                    {
                        ApplySort(Items.OrderBy(keySelector));
                        break;
                    }
                case System.ComponentModel.ListSortDirection.Descending:
                    {
                        ApplySort(Items.OrderByDescending(keySelector));
                        break;
                    }
            }
        }

        public void Sort(Func keySelector, IComparer comparer)
        {
            ApplySort(Items.OrderBy(keySelector, comparer));
        }

        private void ApplySort(IEnumerable sortedItems)
        {
            var sortedItemsList = sortedItems.ToList();

            foreach (var item in sortedItemsList)
            {
                Move(IndexOf(item), sortedItemsList.IndexOf(item));
            }
        }
    }
}


Use it in this way:
public class Person
{
public string Name{get;set;}
public int Age {get;set;}
}

public class PersonCollection:SortableObservableCollection
{
public PersonCollection()
{
[...fill collection...]
this.Sort(x => x.Name, ListSortDirection.Ascending);
}
}

Multilanguage applications with C# with database support


As i wrote in an earlier post, the best way to realize a multilanguage application is to get translated text from a database.
This because even if you know 2 or 3 languages, you should be able to sell the application worldwide without even care on what language it is realized.
I think that one of the best database to use for translations is MS Access, because every translator has an office suite installed on his PC, and for him makes no difference translate on Excel or Access, but if you ask him to translate your sentences on "a random SQL data viewer", it can be a pain.
To support multilanguage in my apps i use a method that, given the name of control, returns a string containing the translated text, like:
lblSample.Content = Translation.GetString("lblSample");
The reference to the culture is contained inside Settings, and that's where i modify my language preferences, so when i load the program i know automatically what language i should use.
You can find the link for a working example at the bottom of the page.

To realize a multilanguage selection you need:
- a listbox containing the list of languages,
- an "Apply" button
Features:
- The listbox should automatically detect the new languages
- The application should change not only the texts, but also date/time format, right to left writing and so on.

1#: Create a database file with access like in the sample and add it to the project:

2#: Download the translation class from
here
and paste it in your project,
or you can download the class with the working sample here:
http://www.megaupload.com/?d=H5ISA83P

3#: Add the current culture field on "Settings": this field will be used on all the project to set the national preferences.

4#: Customize the translation class modifying the namespace and the table rererences, if you modified them.
using ChangeLanguage.Properties; // modify the namespace with your project name
[...]
//connection string
        private static DatabaseResourceManager databaseResourceManager = new DatabaseResourceManager(settings.translationsConnectionString);    // here the connection string is declared inside settings; you can declare your own here.
[...]
OleDbCommand command = new OleDbCommand("Select * From Translations"); // Here there is the reference to table name
[...]
command.CommandText = "SELECT [key], [" + language + "] " + "FROM Translations"; // Here there is another reference to table name

5#: Create the GUI like in the example:
if you use xaml you can use this code:
    
        
        
        

6# Then in the main window you can write methods to fill the language comboBox
        /// 
 Detects languages in database and fill the listbox 
        private void LoadCmbItems()
        {
            try
            {
                List cultureList = Translations.GetCultureList();
                listLanguages.ItemsSource = cultureList;
                listLanguages.SelectedItem = settings.currentCulture;
                Date = DateTime.Now;
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "Language Database error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
and to load / change texts (but usually i do this only on the launch of application)
        private void SetTextsInCurrentLanguage()
        {
            this.Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag);
            LoadCmbItems();
            lblLanguages.Content = Translations.GetString("lblLanguages");
            btnApply.Content = Translations.GetString("btnApply");
            btnButton.Content = Translations.GetString("btnButton");
            lblLabel.Content = Translations.GetString("lblLabel");
            lblDateTime.Content = Translations.GetString("lblDateTime");
        }
You can see that it's really simple to extract translation with this method, it's just needed that you pass the name of the control to the method GetString to receice the translated Content.

7#: Once you wrote all translations, you can update the constructor of the main window to load the localized language and settings:
            Thread.CurrentThread.CurrentCulture = settings.currentCulture;
            Thread.CurrentThread.CurrentUICulture = settings.currentCulture;
            this.DataContext = this;         

            InitializeComponent();

            SetTextsInCurrentLanguage();          
and also create the button "Apply", that basically changes the settings (and in the example refresh the GUI also) :
        private void btnApply_Click(object sender, RoutedEventArgs e)
        {
            settings.currentCulture = (CultureInfo)listLanguages.SelectedItem;
            Thread.CurrentThread.CurrentCulture = settings.currentCulture;  //not so good to see... just to explain how it works
            Thread.CurrentThread.CurrentUICulture = settings.currentCulture;//you should force the user to re-initialize the program
            SetTextsInCurrentLanguage();
        }

You can download the full example here:
http://mesta-automation.com/Downloads/changeLanguage.rar
and read the full documentation here:
http://en.csharp-online.net/Localization_Like_the_Pros

Disclaimer
The sample code described herein is provided on an "as is" basis, without warranty of any kind, to the fullest extent permitted by law. Mestaa.blogspot.com does not warrant or guarantee the individual success developers may have in implementing the sample code on their development platforms or in using their own Web server configurations.