Как получить правильное имя сопоставления из источника привязки, привязанного к List <T>или анонимному типу, для использования в DataGridTableStyle? - PullRequest
15 голосов
/ 07 января 2009

Я пытаюсь создать объект DataGridTableStyle, чтобы я мог контролировать ширину столбцов DataGrid. Я создал объект BindingSource, связанный со списком. На самом деле он связан с анонимным списком типов, созданным через Linq следующим образом (имена переменных изменены для ясности того, что я делаю):

List<myType> myList = new List<myType>(someCapacity);
.
...populate the list with query from database...
.

var query = from i in myList
            select new
            {
                i.FieldA,
                i.FieldB,
                i.FieldC
            };

myBindingSource.DataSource = query;
myDataGrid.DataSource = myBindingSource;

Затем я создаю объект DataGridTableStyle и добавляю его в сетку данных. Однако он никогда не применяет мои свойства стиля таблицы, которые я настроил, потому что я не могу установить правильное свойство myDataGridTableStyle.MappingName.

Я искал в Google около 1/2 часа и продолжаю видеть ссылки на один и тот же вопрос на множестве разных форумов (буквально один и тот же текст, как будто кто-то только что скопировал и вставил вопрос ... Я ненавижу это. ..). Во всяком случае, ни одно из предложений не работает, как говорит парень на всех других сайтах.

Так кто-нибудь здесь знает, что мне нужно установить для свойства MappingName, чтобы мой TableStyle действительно работал правильно? Откуда я могу взять имя? (Он не может быть пустым ..., который работает только с BindingSource, который связан с DataTable или SqlCeResultSet и т. Д.).

Я думаю, что это может быть проблемой, если я использую Linq для создания анонимной, более специализированной версии объектов только с теми полями, которые мне нужны. Должен ли я просто попытаться привязать BindingSource непосредственно к объекту List? Или, может быть, даже привязать DataGrid напрямую к объекту List и вообще пропустить источник привязки.

Спасибо

PS - C #, Compact Framework v3.5

UPDATE:

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

Ответы [ 5 ]

26 голосов
/ 07 января 2009

Я нашел способ заставить эту работу. Я разобью его на части ...


List<myType> myList = new List<myType>(someCapacity);
.
...populate the list with query from database...
.

DataGridTableStyle myDataGridTableStyle = new DatGridtTableStyle();
DataGridTextBoxColumn colA = new DataGridTextBoxColumn();
DataGridTextBoxColumn colB = new DataGridTextBoxColumn();
DataGridTextBoxColumn colC = new DataGridTextBoxColumn();

colA.MappingName = "FieldA";
colA.HeaderText = "Field A";
colA.Width = 50; // or whatever;

colB.MappingName = "FieldB";
.
... etc. (lather, rinse, repeat for each column I want)
.

myDataGridTableStyle.GridColumnStyles.Add(colA);
myDataGridTableStyle.GridColumnStyles.Add(colB);
myDataGridTableStyle.GridColumnStyles.Add(colC);

var query = from i in myList
            select new
            {
                i.FieldA,
                i.FieldB,
                i.FieldC
            };

myBindingSource.DataSource = query.ToList(); // Thanks Marc Gravell

// wasn't sure what else to pass in here, but null worked.
myDataGridTableStyle.MappingName = myBindingSource.GetListName(null); 

myDataGrid.TableStyles.Clear(); // Recommended on MSDN in the code examples.
myDataGrid.TablesStyles.Add(myDataGridTableStyle);
myDataGrid.DataSource = myBindingSource;

Таким образом, в общем случае DataGridTableStyle.MappingName необходимо знать, к какому типу объекта он относится. Поскольку мой объект является анонимным типом (созданным с помощью Linq), я не знаю, что это такое, до момента выполнения. После того, как я привяжу список анонимного типа к источнику привязки, я смогу использовать BindingSource.GetListName (null), чтобы получить строковое представление анонимного типа.

Одна вещь, которую стоит отметить. Если бы я просто привязал myList (тип myType) непосредственно к источнику привязки, я мог бы просто использовать строку «myType» в качестве значения для DataGridTableStyle.MappingName.

Надеюсь, это полезно для других людей!

9 голосов
/ 26 августа 2011

Просто чтобы добавить в сборник ответов уже на этой странице ....

Я был просто разочарован этой же проблемой, пытаясь разработать свое первое приложение, используя формы Windows и компактный каркас (для Windows Mobile 6.5).

То, что я узнал из комментария Марка Гравелла выше, заключается в том, что действительно возможно получить время выполнения MappingName, проверяющее свойства DataGrid. Делая это, я обнаружил, что при привязке моего List<MyType> непосредственно к свойству DataSource DataGrid, DataGrid фактически искал DataGridTableStyle с MappingName

.
"List`1"

вместо любой комбинации List<MyType> или MyType ...

Итак ... поместив «List`1» в поле «Имя сопоставления» в редакторе коллекции DataGridTableStyle (во время разработки), я смог настроить столбцы и другие свойства, не создавая их все во время выполнения.

Я просто надеюсь, что это добавляет еще некоторые ответы к уже предоставленным. Спасибо всем за предоставление мне руководящих принципов.

2 голосов
/ 07 января 2009

Запрос возвращает IEnumerable<T> для некоторых T, но большинство источников привязки (кроме ASP.NET) требуют IList (например, любая реализация IList<T>) - попробуйте добавить .ToList() - т.е.

myBindingSource.DataSource = query.ToList();

A BindingList<T> может работать даже лучше (если он поддерживается в CF 3.5), поскольку он лучше поддерживает некоторые из распространенных сценариев связывания; если вам это нужно (и если предположить, что BindingList<T> существует в CF 3.5), вы можете добавить метод расширения:

static BindingList<T> ToBindingList<T>(this IEnumerable<T> data)
{
    return new BindingList<T>(new List<T>(data));
}

затем позвоните:

myBindingSource.DataSource = query.ToBindingList();

Для полноты, альтернативой IList является IListSource (или даже Type для сценариев чисто метаданных), поэтому DataSource обычно обозначается как object; если бы не эта проблема, компилятор, вероятно, смог бы сообщить вам о проблеме (то есть, если DataSource был определен как IList).

1 голос
/ 23 сентября 2010

Я последовал этому ответу и обнаружил, что имя MappingName всегда являлось именем базового класса (в примере myType).

Так что, кажется, что передача коллекции через BindingSource решает проблему в любом случае, и тогда нет необходимости в BindingSource.GetListName (null).

Также я не нашел необходимости в ToList () запроса, так как BindingSource также сделает это за вас.

Большое спасибо Джейсону Дауну за то, что поставил меня на правильный путь.

0 голосов
/ 31 июля 2016

Я столкнулся с той же проблемой при настройке ширины столбца. После большого количества исследований и разработок я изменил код, как показано ниже, и он работает нормально. Код:

DataGridTableStyle tableStyle = new DataGridTableStyle();
tableStyle.MappingName = dgCustom.DataSource.GetType().Name;

, где dgCustom - это идентификатор DataGrid в dgCustom.DataSource.GetType().Name, который отлично работает.

...