如何从绑定到 List或匿名类型的绑定源获取正确的映射名称,以在 DataGridTableStyle 上使用?

发布于 2024-07-11 13:00:59 字数 1218 浏览 10 评论 0原文

我正在尝试创建一个 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 真正正常工作吗? 我可以从哪里获取名称? (它不能为空......仅适用于绑定到 DataTable 或 SqlCeResultSet 等的 BindingSource)。

我认为我使用 Linq 创建一个匿名的、更专业的对象版本(仅包含我需要的字段)可能会出现问题。 我应该尝试将 BindingSource 直接绑定到 List 对象吗? 或者甚至可以将 DataGrid 直接绑定到 List 对象并完全跳过绑定源。

谢谢

PS - C#,Compact Framework v3.5

更新:

我在下面发布了一个解决我的问题的答案。 无论这是否是最好的方法,它确实有效。 如果您遇到与我相同的问题,值得一看。

I'm trying to create a DataGridTableStyle object so that I can control the column widths of a DataGrid. I've created a BindingSource object bound to a List. Actually it's bound to an anonymous type list created though Linq in the following manner (variable names changed for clarity of what I'm doing):

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;

Then I create a DataGridTableStyle object and add it to the datagrid. However, it never applies my table style properties I set up because I can't seem set the proper myDataGridTableStyle.MappingName property.

I've searched Google for about 1/2 an hour and keep seeing links to the same question throughout a bunch of different forums (literally the same text, like someone just copied and pasted the question... I hate that...). Anyway, none of the suggestions work, just like the guy says on all the other sites.

So does anybody here know what I need to set the MappingName property to in order to have my TableStyle actually work properly? Where can I grab the name from? (It can't be blank... that only works with a BindingSource that is bound to a DataTable or SqlCeResultSet etc.).

I'm thinking it could be an issue with me using Linq to create an anonymous, more specialized version of the objects with only the fields I need. Should I just try to bind the BindingSource directly to the List object? Or maybe even bind the DataGrid directly to the List object and skip the binding source altogether.

Thanks

PS - C#, Compact Framework v3.5

UPDATE:

I've posted an answer below that solved my problem. Whether or not it's the best approach, it did work. Worth a peek if you're having the same issue I had.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

最单纯的乌龟 2024-07-18 13:00:59

我已经找到了使这项工作发挥作用的方法。 我将把它分成几个部分...


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 的值。

希望这对其他人有用!

I've found the way to make this work. I'll break it out into sections...


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;

So basically, the DataGridTableStyle.MappingName needs to know what type of object it is mapping to. Since my object is an anonymous type (created with Linq), I don't know what it is until runtime. After I bind the list of the anonymous type to the binding source, I can use BindingSource.GetListName(null) to get the string representation of the anonymous type.

One thing to note. If I just bound the myList (which is type "myType") directly to the binding source, I could have just used the string "myType" as the value for DataGridTableStyle.MappingName.

Hopefully this is useful to other people!

亢潮 2024-07-18 13:00:59

只是为了添加到此页面上已有的答案集合中......

我只是对尝试使用 Windows 窗体和紧凑框架(适用于 Windows Mobile 6.5)开发我的第一个应用程序的同一问题感到沮丧。

通过 Marc Gravell 上面的评论,我发现确实可以让运行时 MappingName 检查 DataGrid 的属性。 这样做我发现,当将我的 List 直接绑定到 DataGrid 的 DataSource 属性时,DataGrid 实际上正在寻找 MappingName 的 DataGridTableStyle,

"List`1"

而不是 List< ;MyType>MyType...

所以...通过将“List`1”放入 DataGridTableStyle 集合编辑器上的映射名称中(在设计时),我能够自定义列和其他属性,而无需在运行时创建它们。

我只是希望这可以为已经提供的答案添加更多内容。 感谢大家为我提供指导。

Just to add to the collection of answers already on this page....

I was just frustrated with this same issue trying to develop my fist application using windows forms and compact framework (For Windows Mobile 6.5).

What I found out, through Marc Gravell's comment above is that indeed is possible to get the run time MappingName inspecting the properties of the DataGrid. Doing this I found out that when binding my List<MyType> directly to the DataSource property of the DataGrid, the DataGrid was actually looking for a DataGridTableStyle with the MappingName of

"List`1"

instead of any combination of List<MyType> or MyType...

So... by putting "List`1" in the Mapping name on the DataGridTableStyle Collection Editor (at design time), I was able to customize the columns and other properties without having to create them all at run time.

I just hope this adds some more to the answers already provided. Thank you all for providing me with the guidelines.

白芷 2024-07-18 13:00:59

对于某些 T,查询返回 IEnumerable,但大多数绑定源(ASP.NET 除外)需要 IList(例如任何 T) >IList实现) - 尝试添加 .ToList() - 即

myBindingSource.DataSource = query.ToList();

BindingList 可能工作得更好(如果 CF 支持) 3.5)因为它对一些常见的绑定场景有更好的支持; 如果您需要这个(并且假设 CF 3.5 上存在 BindingList),您可以添加一个扩展方法:

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)。

The query returns IEnumerable<T> for some T, but most binding sources (except ASP.NET) require IList (such as any IList<T> implementation) - try adding .ToList() - i.e.

myBindingSource.DataSource = query.ToList();

A BindingList<T> might work even better (if it is supported in CF 3.5) since it has better support for some of the common binding scenarios; if you need this (and assuming BindingList<T> exists on CF 3.5), you can add an extension method:

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

then call:

myBindingSource.DataSource = query.ToBindingList();

For completeness, an alternative to an IList is IListSource (or even Type for purely-metadata scenarios), which is why DataSource is commonly typed as object; if it wasn't for this issue, the compiler probably would have been able to tell you the problem (i.e. if DataSource was defined as IList).

救赎№ 2024-07-18 13:00:59

我遵循这个答案,发现 MappingName 始终是底层类名(示例中的 myType)。

因此,似乎将集合放入 BindingSource 无论如何都可以解决问题,并且不需要 BindingSource.GetListName(null)。

另外,我发现不需要 ToList() 查询,因为 BindingSource 也会为您执行此操作。

非常感谢 Jason Down 让我走上了正轨。

I followed this answer and found that the MappingName always came out to be the underlying class name (myType in the example).

So it seems that putting the collection it through the BindingSource solves the problem anyway and that there is then no need for BindingSource.GetListName(null).

Also I found no need to ToList() the query as the BindingSource will also do this for you.

Many thanks to Jason Down for putting me on the right track.

不知在何时 2024-07-18 13:00:59

我在设置列宽时遇到了同样的问题。
经过大量的研发 D,我更改了代码如下,它工作正常。
代码:

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

其中dgCustomdgCustom.DataSource.GetType().Name中的DataGrid ID,它运行良好。

I was facing same problem for setting column width.
After lot of R & D, i changed code as below and its working fine.
Code:

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

where dgCustom is DataGrid ID in dgCustom.DataSource.GetType().Name which is working perfectly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文