Mam prosty List<string>
i chciałbym, aby był wyświetlany w DataGridView
kolumnie.
Gdyby lista zawierała bardziej złożone obiekty, po prostu ustaliłby listę jako wartość jej DataSource
właściwości.
Ale robiąc to:
myDataGridView.DataSource = myStringList;
Otrzymuję wywołanie kolumny Length
i wyświetlane są długości ciągów.
Jak wyświetlić rzeczywiste wartości ciągów z listy w kolumnie?
c#
binding
datagridview
agnieszka
źródło
źródło
DataPropertyName
Kolumny musi byćValue
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.
źródło
List.ConvertAll(x => new { Value = x});
.Poniższe działania powinny działać, o ile jesteś powiązany z czymkolwiek, co implementuje IEnumerable <string>. Będzie wiązać kolumnę bezpośrednio z samym łańcuchem, a nie ze ścieżką właściwości tego obiektu ciągu.
<sdk:DataGridTextColumn Binding="{Binding}" />
źródło
możesz również użyć linq i typów anonimowych, aby osiągnąć ten sam wynik przy znacznie mniejszej ilości kodu, jak opisano tutaj .
AKTUALIZACJA: blog nie działa, oto treść:
(..) Wartości pokazane w tabeli reprezentują długość łańcuchów zamiast wartości łańcuchowych (!) Może się to wydawać dziwne, ale tak domyślnie działa mechanizm wiązania - dany obiekt będzie próbował dowiązać się do jego pierwszej właściwości obiekt (pierwsza właściwość, jaką może znaleźć). Po przekazaniu instancji klasa String jest powiązana z właściwością String.Length, ponieważ nie ma innej właściwości, która zapewniłaby sam ciąg.
Oznacza to, że aby uzyskać prawidłowe powiązanie, potrzebujemy obiektu opakowującego, który ujawni rzeczywistą wartość ciągu 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 kilku wierszy kodu (głównie do konwersji listy ciągów do listy opakowań ciągów).
Możemy ulepszyć to rozwiązanie za pomocą LINQ i typów anonimowych - użyjemy zapytania LINQ, aby utworzyć nową listę opakowań ciągów (w naszym przypadku opakowanie ciągu będzie typem anonimowym).
var values = from data in testData select new { Value = data }; Table1.SetDataBinding(values.ToList());
Ostatnią zmianą, jaką zamierzamy wprowadzić, 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, wywołując pojedynczą metodę na dowolnej kolekcji ciągów:
źródło
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 został szczegółowo opisany tutaj: http://www.psworld.pl/Programming/BindingListOfString
źródło
Podczas przypisywania naprawdę dużych list za pośrednictwem LINQ mogą wystąpić problemy z wydajnością. Poniższe rozwiązanie jest odpowiednie dla dużych list i bez podklas String:
Ustaw DataGridView (tutaj „Widok”) w tryb wirtualny, utwórz potrzebną kolumnę i zastąp / 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:
źródło
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); }
źródło
Alternatywą jest użycie nowej funkcji pomocniczej, która pobierze wartości z listy i zaktualizuje ją 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; }
Następnie możemy nazwać tę funkcję w następujący sposób:
DisplayStringListInDataGrid(<nameOfListWithStrings>, ref <nameOfDataGridViewToDisplay>, <nameToBeGivenForTheNewColumn>);
źródło