9

我有一个希望绑定到 WPF 网格的集合。

我面临的问题是列数是动态的并且取决于集合。这是一个简单的模型:

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;}
}

我希望我的视图绑定到包含列集合的行集合。

我的 Columns 集合包含一个应该由图像表示的枚举(3 种可能性中的 1 种)。它还包含一个 Message 属性,该属性只应显示在一列中(静态的,只是一些文本信息)。它还包含一个标题字符串,该字符串应显示为该列的标题。

我要显示的链接

请注意,列数是可变的(此时标题设置为确认,但这将更改为表示动态数据)。

更新:这是在实施 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>

这几乎给了我现在想要的东西。我只坚持应该为标题做些什么。欢迎任何建议。

4

4 回答 4

7

ItemsControls您可以为此使用嵌套

这是一个基本示例:

<!-- 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>
于 2012-12-11T16:43:22.583 回答
2

使用网格方法可能会使事情变得比应有的更复杂。您是否尝试过更改列表视图的模板,或者为此目的使用 DataGrid?

例如,看看这个项目: http: //www.codeproject.com/Articles/25058/ListView-Layout-Manager

或者这个: http: //www.codeproject.com/Articles/16009/A-Much-Easier-to-Use-ListView

如果您使用 Grid,我相信您必须在后面添加大量代码来管理列和行的数量、它们的大小、单元格内容......而 ListView/DataGrid 将让您通过动态执行此操作模板。

于 2012-12-11T12:16:06.333 回答
1

使用代码创建网格,如http://msdn.microsoft.com/en-us/library/system.windows.controls.grid(v=vs.90).aspx#feedback

创建一个 ColumnDefinition 类型的属性,(并使用属性更改)来创建列。

于 2014-01-10T00:45:16.470 回答
0

还可以选择使用动态对象来创建列。这有点费力,但结果非常有效,而且解决方案通常非常灵活。

这将向您展示动态对象的基础知识 将 DynamicObject 绑定到具有自动列生成的 DataGrid?

我在使用嵌套对象、具有对象的列然后尝试将单元格内容绑定到对象时遇到了一些麻烦。

这是我提出的一个问题,举了一个如何做到这一点的例子

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

于 2014-11-07T12:25:18.190 回答