Jak powiązać listę z kontrolką DataGridView?

Mam prosty List<string> i chciałbym, aby był wyświetlany w kolumnie DataGridView.
Jeśli lista zawiera bardziej złożone obiekty, po prostu ustali listę jako wartość swojej właściwości DataSource.

Ale kiedy to robisz:

myDataGridView.DataSource = myStringList;

Otrzymuję kolumnę o nazwie Length i wyświetlane są długości łańcuchów.

Jak wyświetlić rzeczywiste wartości łańcucha znaków z listy w kolumnie?

Author: Shin, 2009-01-26

8 answers

To dlatego, że DataGridView szuka właściwości zawierających obiekty. Dla string jest tylko jedna właściwość-length. Więc potrzebujesz owijki do takiego Sznurka

public class StringValue
{
    public StringValue(string s)
    {
        _value = s;
    }
    public string Value { get { return _value; } set { _value = value; } }
    string _value;
}

Następnie połącz obiekt List<StringValue> z siatką. Działa

 63
Author: sinm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-18 23:54:48

Spróbuj tego:

IList<String> list_string= new List<String>();
DataGridView.DataSource = list_string.Select(x => new { Value = x }).ToList();
dgvSelectedNode.Show();
Mam nadzieję, że to pomoże.
 79
Author: Tamanna Jain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-12 17:28:25

Poniżej powinno działać tak długo, jak jesteś związany z wszystkim, co implementuje IEnumerable . Kolumna zostanie powiązana bezpośrednio z samym łańcuchem znaków, a nie ze ścieżką właściwości tego obiektu łańcuchowego.

<sdk:DataGridTextColumn Binding="{Binding}" />
 19
Author: jamisonLikeCode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-15 23:47:25

Możesz również użyć typów linq i anonymous, aby osiągnąć ten sam wynik przy znacznie mniejszej ilości kodu, jak opisano tutaj .

UPDATE: blog padł, oto treść:

(..) Wartości pokazane w tabeli przedstawiają długość łańcuchów zamiast wartości łańcuchowych (!) Może to wydawać się dziwne, ale tak działa mechanizm wiązania domyślnie-biorąc pod uwagę obiekt, będzie próbował powiązać z pierwszą właściwością tego obiektu (pierwszą właściwością, którą może znaleźć). Po przejściu instancji String Klasa właściwość, do której wiąże jest String.Długość, ponieważ nie ma innej właściwości, która zapewniłaby rzeczywisty łańcuch.

Oznacza to, że aby uzyskać nasze prawo wiązania, potrzebujemy obiektu wrappera, który wyświetli rzeczywistą wartość łańcucha znaków jako właściwość:

public class StringWrapper
    {
     string stringValue;
     public string StringValue { get { return stringValue; } set { stringValue = value; } }

     public StringWrapper(string s)
     {
     StringValue = s;
     }
  }   

   List<StringWrapper> testData = new List<StringWrapper>();

   // add data to the list / convert list of strings to list of string wrappers

  Table1.SetDataBinding(testdata);

Chociaż to rozwiązanie działa zgodnie z oczekiwaniami, wymaga sporej liczby linii kodu(głównie do konwersji listy łańcuchów na listę owijarek łańcuchów).

Możemy ulepszyć To rozwiązanie używając LINQ i typy anonimowe - użyjemy zapytania LINQ do utworzenia nowej listy wrapperów łańcuchowych (string wrapper będzie anonimowym typem w naszym przypadku).

 var values = from data in testData select new { Value = data };

 Table1.SetDataBinding(values.ToList());

Ostatnią zmianą jest przeniesienie kodu LINQ do metody rozszerzenia:

public static class StringExtensions
  {
     public static IEnumerable CreateStringWrapperForBinding(this IEnumerable<string> strings)
     {
     var values = from data in strings
     select new { Value = data };

     return values.ToList();
     }

W ten sposób możemy ponownie użyć kodu przez wywołanie pojedynczej metody na dowolnej kolekcji łańcuchów:

Table1.SetDataBinding(testData.CreateStringWrapperForBinding());
 12
Author: Jarek Kardas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-21 15:54:17

Jest to częsty problem, innym sposobem jest użycie obiektu DataTable

DataTable dt = new DataTable();
dt.Columns.Add("column name");

dt.Rows.Add(new object[] { "Item 1" });
dt.Rows.Add(new object[] { "Item 2" });
dt.Rows.Add(new object[] { "Item 3" });

Ten problem jest szczegółowo opisany tutaj: http://www.psworld.pl/Programming/BindingListOfString

 8
Author: user1246920,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-03 15:08:15

Spróbuj tego:

//i have a 
List<string> g_list = new List<string>();

//i put manually the values... (for this example)
g_list.Add("aaa");
g_list.Add("bbb");
g_list.Add("ccc");

//for each string add a row in dataGridView and put the l_str value...
foreach (string l_str in g_list)
{
    dataGridView1.Rows.Add(l_str);
}
 3
Author: Neojt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-09 20:35:44

Możesz napotkać problemy z wydajnością przy przypisywaniu naprawdę dużych list przez LINQ. Następujące rozwiązanie jest odpowiednie dla dużych list i bez podklasowania łańcucha:

Ustaw DataGridView (tutaj "widok") w tryb wirtualny, Utwórz potrzebną kolumnę i Nadpisz / Zarejestruj dla zdarzenia CellValueNeeded

private void View_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
    // Optionally: check for column index if you got more columns
    e.Value = View.Rows[e.RowIndex].DataBoundItem.ToString();
}

Następnie możesz po prostu przypisać swoją listę do DataGridView:

List<String> MyList = ...
View.DataSource = MyList;
 2
Author: user3042599,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-08 13:23:31

Alternatywą jest użycie nowej funkcji pomocniczej, która pobierze wartości z listy i zaktualizuje w DataGridView w następujący sposób:

    private void DisplayStringListInDataGrid(List<string> passedList, ref DataGridView gridToUpdate, string newColumnHeader)
    {
        DataTable gridData = new DataTable();
        gridData.Columns.Add(newColumnHeader);

        foreach (string listItem in passedList)
        {
            gridData.Rows.Add(listItem);
        }

        BindingSource gridDataBinder = new BindingSource();
        gridDataBinder.DataSource = gridData;
        dgDataBeingProcessed.DataSource = gridDataBinder;
    }

Wtedy możemy wywołać tę funkcję w następujący sposób:

    DisplayStringListInDataGrid(<nameOfListWithStrings>, ref <nameOfDataGridViewToDisplay>, <nameToBeGivenForTheNewColumn>);
 0
Author: Sudeep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-30 18:39:26