在数据绑定flowdocument中插入分隔符(空白行)

在我的MVVM WPF应用程序中,我使用了一个数据绑定flowdocument。 我使用这里描述的技术能够将我的数据绑定到flowdocument。 我的flowdocument绑定到我的viewmodel中的公共属性。 该属性是一个自定义类型的ienumerable,如下所示:

public IEnumerable<Person> Persons
{
    get { return _persons; }
    set { _persons = value; }
}

flowdocument显示在FlowDocumentScrollViewer控件中。 该文件看起来像:

code    name    lastname
----    -----   ---------
1       john    johnson
1       peter   peterson
2       jane    jane
3       john    doe

绑定工作正常,但我想在每个不同的代码后添加一个空行:

code    name    lastname
----    -----   ---------
1       john    johnson
1       peter   peterson

2       jane    jane

3       john    doe

我认为Xaml是:

<FlowDocumentScrollViewer>
  <FlowDocument>
    <flowdoc:ItemsContent ItemsSource="{Binding Path=Persons}">
      <flowdoc:ItemsContent.ItemsPanel>
        <DataTemplate>
          <flowdoc:Fragment>
            <Table BorderThickness="1" BorderBrush="Black">
              <TableRowGroup flowdoc:Attached.IsItemsHost="True">
                <TableRow Background="LightBlue">
                  <TableCell>
                   <Paragraph>ronde</Paragraph>
              </TableCell>
              <TableCell>
                <Paragraph>hal</Paragraph>
              </TableCell>
              <TableCell>
                <Paragraph>datum</Paragraph>
              </TableCell>
            </TableRow>
          </TableRowGroup>
        </Table>
      </flowdoc:Fragment>
    </DataTemplate>
  </flowdoc:ItemsContent.ItemsPanel>
  <flowdoc:ItemsContent.ItemTemplate>
    <DataTemplate>
      <flowdoc:Fragment>
        <TableRow>
          <TableCell>
            <Paragraph>
              <flowdoc:BindableRun BoundText="{Binding Path=Code}" />
            </Paragraph>
          </TableCell>
          <TableCell>
            <Paragraph>
              <flowdoc:BindableRun BoundText="{Binding Path=Name}" />
            </Paragraph>
          </TableCell>
          <TableCell>
            <Paragraph>
              <flowdoc:BindableRun BoundText="{Binding Path=LastName}" />
            </Paragraph>
          </TableCell>
        </TableRow>
      </flowdoc:Fragment>
    </DataTemplate>
  </flowdoc:ItemsContent.ItemTemplate>
</flowdoc:ItemsContent>

有关如何在不违反MVVM规则的情况下提出任何建议? 数据绑定流程文档似乎与不灵活布局的价格相关。

提前致谢


为了分组您的数据,请使用像这样的CollectionViewSource

<Window.Resources>
    <CollectionViewSource x:Key="groupView" Source="{Binding Path=Persons}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="Code"/>
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
</Window.Resources>
<Grid>
    <FlowDocumentScrollViewer>
        <FlowDocument>
            <flowdoc:ItemsContent ItemsSource="{Binding Source={StaticResource groupView}}">
               ....
            </flowdoc:ItemsContent>
        </FlowDocument>
    </FlowDocumentScrollViewer>
</Grid>

上面的CollectionViewSource元素通过代码对Persons列表进行排序并确定组。

此外,您必须修改ItemsContent类,因为MSDN文章中的那个不支持分组。 这是一个非常简单的例子,你可以如何实现这一点:

private void GenerateContent(DataTemplate itemsPanel, DataTemplate itemTemplate, IEnumerable itemsSource)
{
    Blocks.Clear();
    if (itemTemplate != null && itemsSource != null)
    {
        FrameworkContentElement panel = null;

        if (panel == null)
        {
            if (itemsPanel == null)
            {
                panel = this;
            }
            else
            {
                FrameworkContentElement p = Helpers.LoadDataTemplate(itemsPanel);
                if (!(p is Block))
                {
                    throw new Exception("ItemsPanel must be a block element");
                }
                Blocks.Add((Block)p);
                panel = Attached.GetItemsHost(p);
                if (panel == null)
                {
                    throw new Exception("ItemsHost not found. Did you forget to specify Attached.IsItemsHost?");
                }
            }
        }

        // *** START NEW CODE ***
        ICollectionView view = itemsSource as ICollectionView;
        if (view != null)
        {
            foreach (object group in view.Groups)
            {
                GenerateContentForUngroupedItems(itemsPanel, itemTemplate, ((CollectionViewGroup)group).Items, panel);
                if (panel is TableRowGroup)
                {
                    TableRow row = new TableRow();
                    row.Cells.Add(new TableCell());
                    ((TableRowGroup)panel).Rows.Add(row);
                }
            }
        }
        else
        {
            GenerateContentForUngroupedItems(itemsPanel, itemTemplate, itemsSource, panel);
        }
        // *** END NEW CODE ***
    }
}

private void GenerateContentForUngroupedItems(DataTemplate itemsPanel, DataTemplate itemTemplate,
                                                IEnumerable itemsSource, FrameworkContentElement panel)
{
    foreach (object data in itemsSource)
    {
        FrameworkContentElement element = Helpers.LoadDataTemplate(itemTemplate);
        element.DataContext = data;
        Helpers.UnFixupDataContext(element);
        if (panel is Section)
        {
            ((Section) panel).Blocks.Add(Helpers.ConvertToBlock(data, element));
        }
        else if (panel is TableRowGroup)
        {
            ((TableRowGroup) panel).Rows.Add((TableRow) element);
        }
        else
        {
            throw new Exception(String.Format("Don't know how to add an instance of {0} to an instance of {1}",
                element.GetType(), panel.GetType()));
        }
    }
}

上面的大多数代码都来自原始的MSDN文章; 我做的唯一改变是这些:

  • foreach循环移至新方法GenerateContentForUngroupedItems
  • 将循环外部的面板创建代码(“ if (panel==null) ”)移出。
  • 添加了标记为NEW CODE
  • 修改后的代码所做的是:如果项目源不是集合视图,则其工作方式与原始MSDN代码完全相同。 如果项目源是一个集合视图,则调用两个嵌套循环:

  • 外循环遍历所有组。
  • 内循环遍历当前组中的所有项目。
  • 内部循环有效地与MSDN文章中的原始foreach循环相同。

    在上面添加的代码中,空行表格行由这些行添加:

    TableRow row = new TableRow();
    row.Cells.Add(new TableCell());
    ((TableRowGroup)panel).Rows.Add(row);
    

    这段代码当然不是非常通用的。 对于通用解决方案,像ItemsPanelItemTemplate属性一样,将新的依赖项属性添加到包含数据模板的ItemsContent控件中。 然后,您可以在该组的最后插入任意文本。

    结果如下所示:


    你需要的是分组。 它保持在MVVM规则中。

    话虽如此,一个快速的谷歌在流文档上分组并没有立即向我展示任何东西。 也许看看flowdocument wpf分组。

    一种解决方案可能是使用数据网格。 你可以使用mvvm将它组合在一起,并使它看起来像你上面描述的布局。

    链接地址: http://www.djcxy.com/p/50467.html

    上一篇: Insert separator (blank line) in databound flowdocument

    下一篇: Databind a read only dependency property to ViewModel in Xaml