Search code examples
wpfflowdocument

Repeating databound item in WPF FlowDocument


I have a flowdocument in WPF that looks like this:

<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Paragraph FontFamily="Georgia">
        <StackPanel>
            <TextBlock Text="{Binding Path=Title}"/>
            <TextBlock Text="{Binding Path=AssignedTo}"/>
        </StackPanel>
    </Paragraph>
</FlowDocument>

instead of giving the DataContext a class with the Title and AssignedTo property, I would like to give it a List of that class and have the flowdocument show each of them objects. Can someone tell me how to form the XAML in the flowdocument to do this?


Solution

  • Who knows, maybe as simple as the following code sample will work for you, Ajma:

    <Window x:Class="WpfTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:WpfTest="clr-namespace:WpfTest"
        xmlns:System="clr-namespace:System;assembly=mscorlib"
        xmlns:Collections="clr-namespace:System.Collections;assembly=mscorlib"
        Title="Bound Inlines Sample" Height="300" Width="300">
      <Window.Resources>
        <Collections:ArrayList x:Key="array">
          <System:String>Hello</System:String>
          <System:String>World</System:String>
          <System:String>!</System:String>
        </Collections:ArrayList>
      </Window.Resources>
      <Grid>
        <FlowDocumentReader>
          <FlowDocument>
            <Paragraph FontFamily="Georgia">
                <ItemsControl ItemsSource="{StaticResource array}"/>            
            </Paragraph>
          </FlowDocument>
        </FlowDocumentReader>
      </Grid>
    </Window>
    

    If it's not, you can always create your own attached property and do whatever you can imagine inside property changed notification. Here is a small sample with Span control:

    CS:

    public class SpanOperations : DependencyObject
    {
      public static IEnumerable GetInlineSource(DependencyObject obj)
      {
        return (IEnumerable)obj.GetValue(InlineSourceProperty);
      }
    
      public static void SetInlineSource(DependencyObject obj, IEnumerable value)
      {
        obj.SetValue(InlineSourceProperty, value);
      }
    
      public static readonly DependencyProperty InlineSourceProperty =
          DependencyProperty.RegisterAttached("InlineSource", typeof(IEnumerable), typeof(SpanOperations), new UIPropertyMetadata(null, OnInlineSourceChanged));
    
      private static void OnInlineSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
        var span  = d as Span;
        if (span == null)
        {
          // It's a demo only. Can work with only spans... 
          return;
        }
        span.Inlines.Clear();
    
        var inlines = e.NewValue as IEnumerable;
        if (inlines != null)
        {
          foreach (var inline in inlines)
          {
            // We assume only inlines will come in collection:
            span.Inlines.Add(inline as Inline);
          }
    
        }
      }
    }
    

    XAML

    <Window x:Class="WpfTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:WpfTest="clr-namespace:WpfTest"
        xmlns:Collections="clr-namespace:System.Collections;assembly=mscorlib"
        Title="Bound Inlines Sample" Height="300" Width="300">
      <Window.Resources>
        <Collections:ArrayList x:Key="array">
          <Run>Hello</Run>
          <LineBreak/>
          <Run>Hello</Run>
          <LineBreak/>
          <Bold>
            <Run>Hello</Run>
          </Bold>
        </Collections:ArrayList>
      </Window.Resources>
      <Grid>
        <FlowDocumentReader>
          <FlowDocument>
            <Paragraph FontFamily="Georgia">
              <Span WpfTest:SpanOperations.InlineSource="{Binding Source={StaticResource array}}"/>
            </Paragraph>
          </FlowDocument>
        </FlowDocumentReader>
      </Grid>
    </Window>
    

    Hope this helps :)