Как привязать список к элементу управления DataGridView?



у меня простой List<string> и я хотел бы, чтобы он отображался в

1086   8  

8 ответов:

это потому, что 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 свойство, к которому он привязывается, является String.Длина, так как нет другого свойства, которое обеспечивало бы саму фактическую строку.

это означает, что для получения нашего права привязки нам нужен объект-оболочка, который будет предоставлять фактическое значение строки как свойство:

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

попробуйте это :

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

вы можете столкнуться с проблемами производительности при назначении действительно больших списков через LINQ. Следующее решение подходит для больших списков и без подклассов строки:

установите DataGridView (здесь "вид") в виртуальный режим, создайте нужный столбец и переопределите / зарегистрируйте событие 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;

альтернативой является использование новой вспомогательной функции, которая будет принимать значения из списка и обновлять в 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>);

Comments

    Ничего не найдено.