List <string>을 DataGridView 컨트롤에 바인딩하는 방법은 무엇입니까?


84

나는 간단한 List<string>것이 있고 그것을 DataGridView열에 표시하고 싶습니다 .
목록에 더 복잡한 개체가 포함되어 있으면 목록을 DataSource속성 값으로 설정하면 됩니다.

하지만 이렇게 할 때 :

myDataGridView.DataSource = myStringList;

열이 호출 Length되고 문자열의 길이가 표시됩니다.

열의 목록에서 실제 문자열 값을 표시하는 방법은 무엇입니까?

답변:


70

DataGridView는 포함 된 개체의 속성을 찾기 때문입니다. 문자열에는 길이라는 하나의 속성 만 있습니다. 따라서 다음과 같은 문자열에 대한 래퍼가 필요합니다.

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

그런 다음 List<StringValue>개체를 그리드에 바인딩 합니다. 효과가있다


3
DataPropertyName열의가 있어야합니다Value
레미

그룹화는 어떻습니까? 이제 "A"는 "A"와 같지 않으며 두 그룹 "A"가 있습니다.
Rover

97

이 시도:

IList<String> list_string= new List<String>();
DataGridView.DataSource = list_string.Select(x => new { Value = x }).ToList();
dgvSelectedNode.Show();

이게 도움이 되길 바란다.


13
IList 대신 List를 사용하는 경우 List.ConvertAll(x => new { Value = x});.
Scotty.NET

7
이것은 작동하지만 list_string을 변경해도 DataGridView가 업데이트되지 않습니다.
Pedro77 2013-04-19

Grid를 업데이트하려면 linq 문을 다시 실행해야합니다.
Jeff

1
dgvSelectedNode.Show ()는 무엇입니까?
Duan Walker

18

다음은 IEnumerable <string>을 구현하는 모든 것에 바인딩되어있는 한 작동합니다. 열을 해당 문자열 개체의 속성 경로가 아닌 문자열 자체에 직접 바인딩합니다.

<sdk:DataGridTextColumn Binding="{Binding}" />

이 sugestion을 테스트했으며 제대로 작동했습니다. 다른 솔루션보다 깨끗합니다.
Gustavo Cardoso

7
이것은 실버 라이트에만 국한되지 않습니까?
NoviceProgrammer 2011

2
이것은 WPF에서도 작동합니다 .. 왜 잘못된 댓글에 찬성 투표를 하시겠습니까?
Boppity Bop 2013-06-09

4
원래 질문에 winforms 제어 인 "datagridview"태그가 있기 때문에 반대 투표합니다. 이 솔루션은 winfroms에는 적용되지 않습니다.
VIS

13

여기에 설명 된대로 훨씬 적은 코드로 동일한 결과를 얻기 위해 linq 및 익명 유형을 사용할 수도 있습니다 .

업데이트 : 블로그가 다운되었습니다. 내용은 다음과 같습니다.

(..) 표에 표시된 값은 문자열 값 대신 문자열의 길이를 나타냅니다. (!) 이상하게 보일 수 있지만 기본적으로 바인딩 메커니즘이 작동하는 방식입니다. 객체가 주어진 경우 해당 속성의 첫 번째 속성에 바인딩하려고합니다. 개체 (찾을 수있는 첫 번째 속성). 인스턴스를 전달하면 실제 문자열 자체를 제공하는 다른 속성이 없기 때문에 바인딩되는 속성은 String.Length입니다.

즉, 바인딩을 올바르게하려면 문자열의 실제 값을 속성으로 노출하는 래퍼 개체가 필요합니다.

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);

이 솔루션은 예상대로 작동하지만 꽤 많은 코드 줄이 필요합니다 (대부분 문자열 목록을 문자열 래퍼 목록으로 변환).

LINQ 및 익명 형식을 사용하여이 솔루션을 개선 할 수 있습니다. LINQ 쿼리를 사용하여 새 문자열 래퍼 목록을 만듭니다 (이 경우 문자열 래퍼는 익명 형식이 됨).

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

 Table1.SetDataBinding(values.ToList());

마지막으로 변경하려는 것은 LINQ 코드를 확장 메서드로 이동하는 것입니다.

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();
     }

이렇게하면 모든 문자열 컬렉션에서 단일 메서드를 호출하여 코드를 재사용 할 수 있습니다.

Table1.SetDataBinding(testData.CreateStringWrapperForBinding());

8

이것은 일반적인 문제이며 다른 방법은 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" });

이 문제는 http://www.psworld.pl/Programming/BindingListOfString 에 자세히 설명되어 있습니다.


2
그러나 데이터 테이블은 List <T>보다 무겁고 대부분의 개발자는 데이터 테이블 사용을 피할 것입니다.
Musikero31 2014 년

2

LINQ를 통해 매우 큰 목록을 할당 할 때 성능 문제가 발생할 수 있습니다. 다음 솔루션은 큰 목록에 적합하며 String을 서브 클래 싱하지 않습니다.

DataGridView (여기서는 "View")를 가상 모드로 설정하고 필요한 열을 만들고 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();
}

그런 다음 목록을 DataGridView에 간단히 할당 할 수 있습니다.

List<String> MyList = ...
View.DataSource = MyList;

2

이 시도 :

//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);
}

1
이 질문이 6 살과 같고 답이 맞다는 것을 알고 있습니까?
Hozikimaru 2015

2
먼저 데이터 그리드보기에 열을 추가하거나이 작동하지 않습니다
deltanine

0

대안은 다음과 같이 List에서 값을 가져오고 DataGridView에서 업데이트하는 새 도우미 함수를 사용하는 것입니다.

    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;
    }

그런 다음이 함수를 다음과 같이 호출 할 수 있습니다.

    DisplayStringListInDataGrid(<nameOfListWithStrings>, ref <nameOfDataGridViewToDisplay>, <nameToBeGivenForTheNewColumn>);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.