DataGridView – Konfiguracja kolumn oraz zapis i odczyt stanu

Spora część niestandardowych pakietów kontrolek oferuje wbudowaną obsługę odczytu i zapisu konfiguracji kolumn komponentu DataGridView, np. do pliku XML. Niestety komponent DataGridView, znajdujący się w standardowej bibliotece klas .NET, nie ma wbudowanych odpowiednich funkcji, a nie zawsze możemy wykorzystać pakiety niestandardowe (lub nie chcemy tego robić), dlatego zaprezentuję Wam szybkie i proste rozwiązanie tego problemu.

No to zaczynajmy!

Nasza aplikacja będzie mieć dwa okna. Okno główne oraz okno dialogowe do edycji widoczności kolumn.

Dla komponentu DataGridView ustawiamy opcję AllowUserToOrderColumns na True aby można było zmieniać kolejność kolumn.

Najpierw zajmiemy się konfiguracją widoczności kolumn komponentu. W tym celu użyjemy okna dialogowego, do którego będziemy przekazywali obiekt DataGridView jako parametr dla konstruktora.

Kod klasy okna to w istocie kod konstruktora, w którym zapamiętamy referencję do obiektu DataGridView i wyświetlimy listę jego kolumn oraz kod zdarzenia odpowiedzialnego za zaznaczanie elementów listy w którym na bieżąco będziemy aktualizować widoczność kolumn komponentu DataGridView.

public partial class FrmColumnsConfig : Form
{
    private DataGridView _dataGridView;

    public FrmColumnsConfig(DataGridView dataGridView)
    {
        InitializeComponent();

        _dataGridView = dataGridView;

        for (int i = 0; i < _dataGridView.Columns.Count; i++)
        {
            lstColumns.Items.Add(_dataGridView.Columns[i].HeaderText, _dataGridView.Columns[i].Visible);
        }
    }

    private void lstColumns_ItemCheck(object sender, ItemCheckEventArgs e)
    {
        _dataGridView.Columns[e.Index].Visible = e.NewValue == CheckState.Checked;
    }
}

Następnie do odczytu i zapisu stanu kolumn użyjemy mechanizmu serializacji obiektów dostępnego na platformie .NET. Wykorzystamy do tego klasę XmlSerializer z przestrzeni nazw System.Xml.Serialization.

Rozpoczniemy od utworzenia klasy, w której będziemy przechowywali dane o pojedynczej kolumnie komponentu DataGridView. Klasa ta musi być oznaczona atrybutem Serializable.

[Serializable]
public sealed class ColumnInfo
{
    public string Name { get; set; }
    public int DisplayIndex { get; set; }
    public int Width { get; set; }
    public bool Visible { get; set; }
}

Przechowywane dane to nazwa kolumny, kolejność przy wyświetlaniu, szerokość kolumny oraz informacja o tym, czy jest ona widoczna.

Następnie utworzymy statyczną klasę wspomagającą obsługę nowych funkcji (Helper), które będą dostępne z poziomu całego naszego programu.

public static class DataGridViewHelper
{
    public static void ShowConfigurationWindow(DataGridView dataGridView)
    {
        using (var frmConfig = new FrmColumnsConfig(dataGridView))
        {
            frmConfig.ShowDialog();
        }
    }

    public static void LoadConfiguration(DataGridView dataGridView, string fileName)
    {
        List<ColumnInfo> columns;
        using (var streamReader = new StreamReader(fileName))
        {
            var xmlSerializer = new XmlSerializer(typeof(List<ColumnInfo>));
            columns = (List<ColumnInfo>)xmlSerializer.Deserialize(streamReader);
        }

        foreach (var column in columns)
        {
            dataGridView.Columns[column.Name].DisplayIndex = column.DisplayIndex;
            dataGridView.Columns[column.Name].Width = column.Width;
            dataGridView.Columns[column.Name].Visible = column.Visible;
        }
    }

    public static void SaveConfiguration(DataGridView dataGridView, string fileName)
    {
        var columns = new List<ColumnInfo>();
        for (int i = 0; i < dataGridView.Columns.Count; i++)
        {
            var column = new ColumnInfo();
            column.Name = dataGridView.Columns[i].Name;
            column.DisplayIndex = dataGridView.Columns[i].DisplayIndex;
            column.Width = dataGridView.Columns[i].Width;
            column.Visible = dataGridView.Columns[i].Visible;
            columns.Add(column);
        }

        using (var streamWriter = new StreamWriter(fileName))
        {
            var xmlSerializer = new XmlSerializer(typeof(List<ColumnInfo>));
            xmlSerializer.Serialize(streamWriter, columns);
        }
    }
}

W skład klasy wchodzą tylko trzy metody:

ShowConfigurationWindow – wyświetla okno dialogowe do konfiguracji kolumn dla komponentu DataGridView przekazanego jako parametr.

SaveConfiguration – pobiera dane o kolumnach komponentu DataGridView i umieszcza je w liście obiektów ColumnInfo, a następnie zapisuje (serializuje) zawartość tej listy do pliku XML.

LoadConfiguration – wczytuje (deserializuje) uprzednio zapisaną listę danych o kolumnach z pliku XML i konfiguruje kolumny komponentu DataGridView.

Wywołanie metod helpera znajduje się w kodzie obsługi zdarzeń odpowiednich przycisków okna głównego aplikacji.

Konfiguracja kolumn:

private void btnConfigure_Click(object sender, EventArgs e)
{
    DataGridViewHelper.ShowConfigurationWindow(dgvData);
}

Odczyt danych ze wskazanego pliku XML:

private void btnLoad_Click(object sender, EventArgs e)
{
    using (var dlgOpen = new OpenFileDialog())
    {
        dlgOpen.Filter = "XML files|*.xml";
        if (dlgOpen.ShowDialog() == DialogResult.OK)
        {
            DataGridViewHelper.LoadConfiguration(dgvData, dlgOpen.FileName);
        }
    }
}

I zapis danych do wskazanego pliku XML:

private void btnSave_Click(object sender, EventArgs e)
{
    using (var dlgSave = new SaveFileDialog())
    {
        dlgSave.Filter = "XML files|*.xml";
        if (dlgSave.ShowDialog() == DialogResult.OK)
        {
            DataGridViewHelper.SaveConfiguration(dgvData, dlgSave.FileName);
        }
    }
}

To wszystko na dzisiaj. Mam nadzieję, że ten wpis się komuś przyda 😉

Cała aplikacja jest do pobrania poniżej.

DataGridView konfiguracja
DataGridView konfiguracja
DGVColumnState.zip
55.4 KiB
Pobrano 189 razy
Szczegóły...

Tagi:, , ,

Trackbacks/Pingbacks

  1. C# Extension methods | Developer blog - 21 marca 2012

    […] Myślę, że dobrym przykładem będzie tutaj modyfikacja kodu źródłowego, który znajdziecie w moim wcześniejszym wpisie dotyczącym zapisu i odczytu stanu komponentu DataGridView znajdującego się tutaj . […]

Dodaj komentarz

Uzupełnij * Time limit is exhausted. Please reload the CAPTCHA.