15

我正在尝试创建一个 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#,紧凑框架 v3.5

更新:

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

4

5 回答 5

26

我已经找到了使这项工作的方法。我会把它分成几部分...


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

希望这对其他人有用!

于 2009-01-07T16:42:09.013 回答
9

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

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

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

"List`1"

List<MyType>而不是或MyType...的任何组合

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

我只是希望这会为已经提供的答案增加更多内容。感谢大家为我提供指导方针。

于 2011-08-25T21:01:14.480 回答
2

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

myBindingSource.DataSource = query.ToList();

ABindingList<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为了完整起见, is的替代方案IListSource(甚至Type对于纯元数据场景),这就是为什么DataSource通常键入为object; 如果不是因为这个问题,编译器可能已经能够告诉你问题(即如果DataSource被定义为IList)。

于 2009-01-07T14:03:44.683 回答
1

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

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

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

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

于 2010-09-23T14:20:06.050 回答
0

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

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

dgCustomDataGrid ID 在哪里dgCustom.DataSource.GetType().Name工作得很好。

于 2016-07-31T08:38:40.910 回答