Program Tip

목록을 바인딩하는 방법

programtip 2020. 10. 13. 19:06
반응형

목록을 바인딩하는 방법 DataGridView 컨트롤에?


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

하지만 이렇게 할 때 :

myDataGridView.DataSource = myStringList;

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

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


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

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

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


이 시도:

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

이게 도움이 되길 바란다.


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

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

여기에 설명 된대로 훨씬 적은 코드로 동일한 결과를 얻기 위해 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());

이것은 일반적인 문제이며 다른 방법은 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 에 자세히 설명되어 있습니다.


You might run into performance issues when assigning really large lists through LINQ. Following solution is suitable for large lists and without subclassing String:

Set DataGridView (here "View") to virtual mode, create column you need and override / register for event 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();
}

then you can simply assign your list to DataGridView:

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

Try this :

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

An alternate is to use a new helper function which will take values from List and update in the DataGridView as following:

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

Then we can call this function the following way:

    DisplayStringListInDataGrid(<nameOfListWithStrings>, ref <nameOfDataGridViewToDisplay>, <nameToBeGivenForTheNewColumn>);

참고URL : https://stackoverflow.com/questions/479329/how-to-bind-a-liststring-to-a-datagridview-control

반응형