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

StackOverflow https://stackoverflow.com/questions/420386

Вопрос

Я пытаюсь создать объект 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 около получаса и продолжал видеть ссылки на один и тот же вопрос на множестве разных форумов (буквально один и тот же текст, как будто кто-то просто скопировал и вставил вопрос...Я ненавижу это...).В любом случае, ни одно из предложений не работает, как и говорит этот парень на всех других сайтах.

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

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

Спасибо

PS — C#, Compact Framework v3.5

ОБНОВЛЯТЬ:

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

Это было полезно?

Решение

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


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.

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

Другие советы

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

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

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

"List`1"

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

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

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

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

myBindingSource.DataSource = query.ToList();

А 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).

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top