带有动态列的 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:36:38  来源:igfitidea点击:

wpf grid with dynamic columns

wpfmvvmgridmultiple-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 属性,它应该只显示在一列中(静态的,只是一些文本信息)。它还包含一个标题字符串,该字符串应显示为该列的标题。

The link to what I want to show

我想展示的链接

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 ItemsControlsfor 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

绑定到 XAML 中 WPF DataGridCell 的内容的问题