WPF 网格数据绑定
我有一个只有 1 行的网格。 我希望列的数量由网格的数据上下文确定。
例如,如果我有一个名为“Names”的 ObservableCollection 属性中公开的名称列表,该属性返回“Fred”、“Joe”和“Anne”,我希望网格中包含三列,每列都有一个绑定到每个列的文本框姓名。
到目前为止我的想法:
1)在代码隐藏中手动构建网格,并在 ObservableCollection 更改时重建它。 我没有这样做,因为它看起来有点笨拙,而且不是 WPF 的做事方式。
2) 使用 Grid 的 ColumnDefinitions 属性创建绑定。 这似乎更正确,但 ColumnDefinition 的 Grid 上没有依赖属性。
I have a grid with just 1 row. I would like the amount of columns to be determined by the data context of the grid.
For instance, if I have a list of names exposed in an ObservableCollection property called 'Names' that return "Fred", "Joe", and "Anne", I would like three columns in the grid, each with a textbox bound to each name.
My thoughts so far:
1) Build the grid by hand in the code-behind and rebuild it when the ObservableCollection changes. I didn't go with this as it seemed a bit cludgy and not the WPF way of doing things.
2) Create a binding with the Grid's ColumnDefinitions property. This seemed more correct, but there's not a dependency property on the Grid for ColumnDefinition.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不认为动态修改网格是最好的选择。 这是另一个解决方案。 您可以使用 ListBox,但将 ItemsPanel 替换为您选择的另一个面板。 ListBox 的默认 ItemsPanel 是 VirtualizingStackPanel,方向设置为 Vertical。 由于您希望项目水平显示,因此可以将其替换为 VirtualizingStackPanel,并将方向设置为水平。 当然,您可以根据需要修改 ItemsTemplate 或其他任何内容。
我之前也使用过此方法来创建一个 ListBox,它水平显示项目,但当该行空间不足时,通过使用 WrapPanel 换行到下一行。 您还可以创建自己的自定义面板并替换它们。 我曾经制作了一个随机排列其项目的面板,并将其用于列表框。 我绑定的集合中的每个项目都显示在列表框中的随机位置。 每次刷新布局时,项目都会获得新的位置。
I don't think modifying a Grid on the fly is your best bet. Here's another solution. You can use ListBox, but replace the ItemsPanel with another panel of your choosing. ListBox's default ItemsPanel is VirtualizingStackPanel with Orientation set to Vertical. Since you want your items to display horizontally, you can replace it with VirtualizingStackPanel with Orientation set to Horizontal. Of course, you can modify the ItemsTemplate or anything else as you see fit.
I've also used this method before to create a ListBox which displays the items horizontally, but wraps to the next line when it runs out of room on the line, by using a WrapPanel. You can also create your own custom panels and substitute them. I once made a panel that laid out it's items randomly, and used that for a ListBox. Each item in my bound collection was displayed in a random position within the ListBox. Each time the layout refreshed, the items got a new position.
如果它是 DataGrid, AutoGenerateColumns 属性可以做到这一点。 通过使用 DataGridTemplateColumn,您可以在其中放置文本框控件,而不仅仅是文本。 您需要提供附加到 AutoGenerateColumn 和 AutoGenerateColumnEventArgs(嗨,Microsoft,这是 carpel 隧道调用),将 Column 属性设置为带有文本框的模板列。
我想说你的 ObservableCollection 方式更简单;-P。
If it's a DataGrid, the AutoGenerateColumns property would do this. By using the DataGridTemplateColumn, you can put text box controls instead of just text in there. You'll need to provide an event attached to the AutoGeneratingColumn and in the AutoGeneratingColumnEventArgs (hi, Microsoft, this is carpel tunnel calling), set the Column property to a template column with the text box.
I'd say your ObservableCollection way is simpler ;-P.
如果您可以接受在每行而不是每列中包含名称,则应使用带有 GridView View 属性的 ListView 和一个只是绑定文本框的自定义 CellTemplate。 像这样的事情:
不幸的是,解决方案#2 在 XAML 中是不可能的。 如果您必须将每个名称放在自己的列中,那么解决方案 #1 是您的最佳选择。
If you can accept having the names in each row rather than each column, you should use the ListView with a GridView View property, and a custom CellTemplate that is just a bound textbox. Something like this:
Solution #2 is unfortunately not possible in XAML. Solution #1 is your best bet if you must have each name in its own column.