나는 간단한 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();
이게 도움이 되길 바란다.
List.ConvertAll(x => new { Value = x});
.
다음은 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 에 자세히 설명되어 있습니다.
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;
이 시도 :
//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);
}
대안은 다음과 같이 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>);
DataPropertyName
열의가 있어야합니다Value