带有动态列的 wpf 网格
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13814224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
wpf grid with dynamic columns
提问by zman
I have a collection that I wish to bind to a WPF grid.
我有一个想要绑定到 WPF 网格的集合。
The problem I'm facing is that the number of columns is dynamic and is dependent on a collection. Here is a simple mock up:
我面临的问题是列数是动态的并且取决于集合。这是一个简单的模型:
public interface IRows
{
string Message{get;}
IColumns[] Columns{get;}
}
public interface IColumns
{
string Header {get;}
AcknowledgementState AcknowledgementState{get;}
}
public interface IViewModel
{
ObservableCollection<IRows> Rows {get;}
}
I want my view to bind to the the Rows collection, which contains a collection of Columns.
我希望我的视图绑定到 Rows 集合,该集合包含一个 Columns 集合。
My Columns collection contains an enum which should be represented by an image (1 of 3 possibilities). It also contains a Message property which should only be displayed in one column (static and is just some text information). It also contains a Header string which should be displayed as a header for that column.
我的 Columns 集合包含一个应由图像表示的枚举(3 种可能性中的一种)。它还包含一个 Message 属性,它应该只显示在一列中(静态的,只是一些文本信息)。它还包含一个标题字符串,该字符串应显示为该列的标题。
Note that the number of columns is variable (at the moment the headers are set to Acknowledge but this will change to represent dynamic data).
请注意,列数是可变的(此时标题设置为确认,但这将更改以表示动态数据)。
Update: This is after implementing suggestions from Rachel
更新:这是在实施 Rachel 的建议之后
<ItemsControl
ItemsSource="{Binding Items, Converter={StaticResource PresentationConverter}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid ShowGridLines="true"
local:GridHelpers.RowCount="{Binding RowCount}"
local:GridHelpers.ColumnCount="{Binding ColumnCount}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Row" Value="{Binding RowIndex}"/>
<Setter Property="Grid.Column" Value="{Binding ColumnIndex}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type UI:MessageEntity}">
<TextBox Text="{Binding Message}"></TextBox>
</DataTemplate>
<DataTemplate DataType="{x:Type UI:StateEntity}">
<TextBox Text="{Binding State}"></TextBox>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This almost gives me what I want now. I'm only stuck with what I should do for the headers. Any suggestions are welcome.
这几乎给了我现在想要的东西。我只坚持我应该为标题做些什么。欢迎任何建议。
采纳答案by Rachel
You can use nested ItemsControls
for this
您可以ItemsControls
为此使用嵌套
Here's a basic example:
这是一个基本示例:
<!-- Bind Rows using the default StackPanel for the ItemsPanel -->
<ItemsControl ItemsSource="{Binding Rows}">
<!-- Set the Template for each row to a TextBlock and another ItemsControl -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!-- Need to set Width of name TextBlock so items line up correctly -->
<TextBlock Width="200" Text="{Binding Name}" />
<ItemsControl ItemsSource="{Binding Columns}">
<!-- Use a horizontal StackPanel to display columns -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
回答by Joe
Using a grid approach might make things more complicated than they should be. Have you tried changing the template of a listview, or to use the DataGrid instead for this purpose?
使用网格方法可能会使事情变得比应有的复杂。您是否尝试过更改列表视图的模板,或者为此目的使用 DataGrid?
For an example, take a look at this project: http://www.codeproject.com/Articles/25058/ListView-Layout-Manager
举个例子,看看这个项目:http: //www.codeproject.com/Articles/25058/ListView-Layout-Manager
Or this one: http://www.codeproject.com/Articles/16009/A-Much-Easier-to-Use-ListView
或者这个:http: //www.codeproject.com/Articles/16009/A-Much-Easier-to-Use-ListView
If you go with the Grid, I believe you'll have to add a lot of code behind to manage the amount of columns and rows, their size, the cell content... Whereas a ListView/DataGrid will let you do this dynamically through Templates.
如果你使用网格,我相信你必须添加很多代码来管理列和行的数量、它们的大小、单元格内容......而 ListView/DataGrid 将让你通过模板。
回答by user2330678
Create a Grid using code as shown at http://msdn.microsoft.com/en-us/library/system.windows.controls.grid(v=vs.90).aspx#feedback
使用代码创建网格,如http://msdn.microsoft.com/en-us/library/system.windows.controls.grid(v=vs.90).aspx#feedback
create a property of type ColumnDefinition,( and use property changed ) to create columns.
创建一个 ColumnDefinition 类型的属性,(并使用属性更改)来创建列。
回答by Kezza
There is also the option of using a dynamic object to create your columns. This is a bit laborious but the results are very effective and the solution in general is quite flexible.
还可以选择使用动态对象来创建列。这有点费力,但结果非常有效,而且解决方案通常非常灵活。
This will show you the basics to the dynamic object Binding DynamicObject to a DataGrid with automatic column generation?
这将向您展示动态对象的基础知识 将 DynamicObject 绑定到具有自动列生成的 DataGrid?
I had some trouble using it with nested objects, columns that have objects and then trying to bind cell content to the object.
我在将它与嵌套对象、具有对象的列一起使用时遇到了一些麻烦,然后尝试将单元格内容绑定到该对象。
Here's a question I raised with an example of how to do this
这是我用如何做到这一点的例子提出的一个问题
Problems binding to a the content of a WPF DataGridCell in XAML