В программно добавленных столбцах ListView отображается тип элемента
Я получил ListView в другой сборке и хочу добавить столбец к нему. Элементы в списке являются объектами класса в этой сборке.
Когда я добавляю столбец, как это
var col : GridViewColumn = new GridViewColumn();
col.Header = "Header text";
list.View.Columns.Add(col);
столбец появляется, но все строки в списке имеют имя типа элемента в этом новом столбце. Даже когда я изменяю значение нового столбца (itemclass.Items[newColIdx] = "zz"
) это не отображается. Нет привязки данных или шаблонов ячеек.
Это почему?
Редактировать: Может быть, я могу улучшить вопрос: если ListView.Items содержит массив класса A - как вы управляете, какие элементы A отображаются, как в GridView? Мне нужен реверс-инжиниринг, и DisplayMemberBinding имеет значение null, поэтому он не использует привязку данных AFAIK.
Вопрос о вознаграждении: когда ToString()
вызывается для каждого элемента (который представляет строку), как это отображается в столбцах GridView? Как я должен изменить элемент в строке, чтобы заполнить новый столбец?
Особая проблема при попытке найти это решение состоит в том, что он выполняется в изолированной программной среде JScript в более крупном приложении C# .NET, и не предоставляется никакой возможности отладки, кроме использования окон сообщений и отражения.
Редактировать: проблема в том, что я пишу JScript, который запускается в стороннем.NET-приложении и дает мне возможность делать много всего возможного с.NET. Это скрипт, добавляющий функции в просмотр списка. Я могу получить доступ к списку, и он заполнен данными базы данных сторонним приложением. Я не знаю, как это происходит. Я могу программно добавлять пользовательские строки с пользовательским содержимым (не связанным с БД). Но когда я добавляю пользовательский столбец, я не вижу его значения в строках den.
Добавленные строки имеют тип 3rdParty.ListRow
и содержать свойство Items
которому я назначаю строковый массив. Значения массива отображаются в репрезентативных столбцах, но не в добавленных столбцах. Там я только получаю текст 3rdParty.ListRow
потому что ToString()
был вызван на ListRow.
Итак: Как я могу указать новые столбцы (например, индекс 5) для отображения ListRow.Items[5]
и не ListRow.ToString()
? Мне понравилось делать то же самое, что и в уже существующих столбцах. Кажется, что все свойства, упомянутые Алексом, там не определены. Как бы я установить DataMemberBinding
добиться сопоставления с ListRow.Items[5]
?
2 ответа
Если столбец не имеет DisplayMemberBinding
или же CellTemplate
затем ToString вызывается для каждого элемента в сетке, а оцененное значение используется в качестве содержимого ячейки.
Например, если у вас есть класс:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return LastName;
}
}
Если вы связываете коллекцию Person
в виде сетки:
var people =
new List<Person>
{
new Person { FirstName = "Peter", LastName = "Smith" },
new Person { FirstName = "Steve", LastName = "White" },
new Person { FirstName = "Dave", LastName = "Gates" },
};
listView1.ItemsSource = people;
И если вы создаете новый столбец без привязки, то LastName будет показан в этом столбце, потому что переопределен ToString()
возвращается LastName
, Если вы измените ToString
возвращать FirstName
тогда новый столбец покажет FirstName
,
Надеюсь, я правильно понял ваш вопрос.
[Редактировать]
Если вы добавите много новых столбцов и не используете DisplayMemberBinding
тогда все новые столбцы будут оценивать и показывать ToString()
результат. Вам нужно установить DisplayMemberBinding
показать конкретную собственность.
var newColumn = new GridViewColumn();
newColumn.Header = "Test";
newColumn.DisplayMemberBinding = new Binding("FirstName");
gridView.Columns.Add(newColumn);
[Редактировать] Ответы на ваши вопросы:
Когда ToString() вызывается для каждого элемента (который представляет строку), как это отображается в столбцах GridView? Как я должен изменить элемент в строке, чтобы заполнить новый столбец?
ToString вызывается при визуализации предъявителя ячейки, если только вы не указали привязку или шаблон, который также будет использовать привязку в конце. Вы не можете изменить элемент строки, чтобы управлять его представлением в сетке, если только вы не переопределите ToString или свойства, связанные со столбцами.
Не уверен, что полностью понимаю вашу проблему. Вы добавляете новый столбец, верно? Почему бы вам не установить свойство DisplayMemberBinding для вашего столбца? Если вы сделаете это, вы сможете показать в столбце все, что вы хотите.
[Редактировать]
Я думаю, что я ответил на ваш вопрос щедрости:). Я думаю, что я уже получил награду:).
Тем не менее, вот ответ на ваш следующий вопрос:
Как бы я установить DataMemberBinding для достижения сопоставления ListRow.Items[5]?
Ответ:
newColumn.DisplayMemberBinding = new Binding("Items[5]");
Это потому, что вызывается метод ToString() каждого элемента в списке. Если не переопределено наследующим типом, Object.ToString() возвращает имя типа объекта.
Есть еще одна проблема, из-за которой ваш список не будет вызывать события изменений, поэтому пользовательский интерфейс не знает, что данные изменились, и нуждается в обновлении.