Не секрет, что пользователь, проработавший некоторое время с программой, пытается ее настроить «под себя»: поменять цветовую гамму, расположение панелей инструментов, изменить ширину столбцов в сетке DataGridView… На последней возможности остановимся по подробнее.

За разрешение изменять ширину столбца отвечает свойство AllowUserToResizeColumns элемента управление DataGridView, которое по умолчанию установлено в true. Поэтому, если просто поместить компонент DataGridView на форму, пользователь сможет изменять ширину столбцов по своему усмотрению. Однако, если приложение будет закрыто, то все изменения будут потеряны и, при последующем запуске программы, ширина столбцов будет установлена до размеров, заданных программистом во время разработки программы.

Для того, чтобы устранить это досадное «недоразумение» необходимо предусмотреть сохранение ширины столбцов при закрытии приложения и восстановление ее при запуске программы. Раньше для этих целей использовался реестр Windows, теперь же принято «гадить» в профиле пользователя. Хранение параметров приложения в конфигурационном в каталоге с исполняемым файлом плохая идея: есть люди, работающие под учетной записью, не обладающей правами администратора (их немного, но они есть ;), для которых запись в Program Files запрещена (справедливо для файловой системы NTFS).

Первое что приходит в голову — это создать параметр типа Int32 для каждого столбца DataGridView в Application Settings. Очевидным минусом данного подхода является большой объем работы, если столбцов много. Покопавшись в MSDN можно найти интерфейс IPersistComponentSettings, который как раз и предназначен для этих целей. В интерфейсе определено 3 метода и два свойства, описывать которые нет необходимости, благо MSDN давно доступен любому желающему на Великом и Могучем (http://msdn.microsoft.com/ru-ru/library/system.configuration.ipersistcomponentsettings_members.aspx).

За дело. Для начала на потребуется класс для хранения информации о столбце:

public class MyColumnInfo
{
    public MyColumnInfo() { }
    public String Name;         // имя столбца
    public Int32 Width;         // ширина столбца
    public Int32 DisplayIndex;  // порядок расположения
}

Теперь необходимо создать класс-наследник от ApplicationSettingsBase, в котором определим свойство ColumnInfo, а поскольку количество столбцов заранее неизвестно, удобно использовать класс List, сериализация которого оказывается весьма кстати.

class MySettings : ApplicationSettingsBase
{
    public MySettings(string settingsKey) : base(settingsKey) { }

    [UserScopedSetting()]
    [DefaultSettingValueAttribute("")]
    public List ColumnInfo
    {
        get { return (List)this["ColumnInfo"]; }
        set { this["ColumnInfo"] = value; }
    }
}

Создадим свой собственный класс DataGridView:

public class MyDataGridView : DataGridView, IPersistComponentSettings
{
    private bool _save = true;
    private MySettings _settings;

    public MyDataGridView()
    {
        _settings = new MySettings(Name);
    }
}

Реализуем интерфейс IPersistComponentSettings:

#region IPersistComponentSettings Members
public void LoadComponentSettings()
{
    _settings.Reload();

    foreach (MyColumnInfo colInfo in _settings.ColumnInfo)
    {
        DataGridViewColumn col = this.Columns[colInfo.Name];
        if (col != null)
        {
            col.Width = colInfo.Width;
            col.DisplayIndex = colInfo.DisplayIndex;
        }
    }
}

public void ResetComponentSettings()
{
    _settings.Reset();
}

public void SaveComponentSettings()
{
    _settings.ColumnInfo.Clear();

    foreach (DataGridViewColumn col in this.Columns)
    {
        MyColumnInfo colInfo = new MyColumnInfo();
        colInfo.Name = col.Name;
        colInfo.Width = col.Width;
        colInfo.DisplayIndex = col.DisplayIndex;
        _settings.ColumnInfo.Add(colInfo);
    }
    _settings.Save();
}

public bool SaveSettings
{
    get { return _save; }
    set { _save = value; }
}

public string SettingsKey
{
    get { return Name; }
    set { _settings.SettingsKey = value; }
}
#endregion

После компиляции на панели инструментов (Toolbox) появиться новый компонент:

Собственный DataGridView

Теперь его можно использовать как обычный DataGridView.

Скачать пример использования можно здесь sample.rar.