WPF教程

FlowDocument in WPF

时间:2014-3-12 16:25:10  作者:WPF之家  来源:http://www.wpf123.com/  查看:580  评论:0
内容摘要:<FlowDocument xmlns=’http://schemas.microsoft.com/winfx/2006/xaml/presentation’ xmlns:x=’http://schemas.microsoft.com/winfx/2006/xaml...
<FlowDocument
  xmlns=’http://schemas.microsoft.com/winfx/2006/xaml/presentation’
  xmlns:x=’http://schemas.microsoft.com/winfx/2006/xaml’>
  <Paragraph>The quick <Bold>brown fox</Bold> jumps over the lazy dog.
</Paragraph>
</FlowDocument>

基本概念:

Flow document是Collections of blocks.Block是继承System.Windows.Documents.Block Class;

 重要的BlockType:

Block Description
Paragraph段落 Contains (potentially richly formatted) text.
List列表 Contains lists of various kinds (numbered, bulleted, and so on).
Table表格 Contains tables similar to those in Microsoft Word or HTML.
BlockUIContainer可以包括多个UI Elements Contains various UI elements that are made part of the overall flow.
Section一组Block Contains a group of other blocks. Sections are handy for applying common attributes to a group of blocks, such as the same font attributes to multiple paragraphs

XAML:
<FlowDocument>
  <Paragraph>Hello World!</Paragraph>
</FlowDocument>
c#代码:
FlowDocument doc = new FlowDocument();
Paragraph para = new Paragraph();
para.Inlines.Add(“Hello World!”);
doc.Blocks.Add(para);
Figue,Floater,LineBreak;

<Paragraph>
  <Figure Width=”200”>
    <BlockUIContainer>
      <Image Source=”Pictures\Humpback Whale.jpg” />
    </BlockUIContainer>
    <Paragraph Foreground=”Blue” FontFamily=”Consolas”>
        The Whale</Paragraph>
  </Figure>
  The quick brown fox jumps over the lazy dog. The quick brown...
</Paragraph>

显示FlowDocument的控件:FlowDocumentReader (支持分页,预览,缩放,查找等功能),FlowDocumentScrollViewer,

<FlowDocument IsOptimalParagraphEnabled=”true” 
    IsHyphenationEnabled=”true”>
IsOptimalParagraphEnabled(平均分配段落之间的空格):distribute white space as evenly as possible within a given paragraph, resulting in a much improved reading experience
IsHyphenationEnabled=”true” (断字功能)

导出功能/导入其他格式(RTF,XAML等)文件的功能:

doc = new FlowDocument();

var content = new TextRange(doc.ContentStart, doc.ContentEnd);
            if (content.CanSave(DataFormats.Rtf))
            {
                using (var stream = new FileStream(@"c:\temp\text.rtf", FileMode.Create))
                {
                    content.Save(stream, DataFormats.Rtf);                    
                }
            }

            FlowDocument doc2 =new FlowDocument();
            var content2 = new TextRange(doc2.ContentStart, doc2.ContentEnd);

            if (content2.CanLoad(DataFormats.Rtf))
            {
                using (var stream = new FileStream(@"c:\temp\text.rtf", FileMode.Open))
                {
                    content2.Load(stream, DataFormats.Rtf);
                }
            }

打印文档:

PrintDialog printDialog = new PrintDialog(); 
                if (printDialog.ShowDialog() == true) {

                FlowDocument fd = new FlowDocument();
                    var stream = new FileStream(@"c:\temp\text.rtf", FileMode.Open);
                    
                TextRange tr = new TextRange(fd.ContentStart, fd.ContentEnd);

                tr.Load(stream, DataFormats.Rtf);

                stream.Close();
                fd.ColumnWidth = printDialog.PrintableAreaWidth;                
                                   
                printDialog.PrintDocument(((IDocumentPaginatorSource)fd).DocumentPaginator, "myReport");

            }

如果需要自定义的Header/Footer,则需要实现DocumentPaginator接口:

public class HeaderedFlowDocumentPaginator : DocumentPaginator
    {
        private DocumentPaginator flowDocumentpaginator;


        public HeaderedFlowDocumentPaginator(FlowDocument document)
        {
            flowDocumentpaginator = ((IDocumentPaginatorSource)document).DocumentPaginator;
        }


        public override bool IsPageCountValid
        {
            get { return flowDocumentpaginator.IsPageCountValid; }
        }


        public override int PageCount
        {
            get { return flowDocumentpaginator.PageCount; }
        }


        public override Size PageSize
        {
            get { return flowDocumentpaginator.PageSize; }
            set { flowDocumentpaginator.PageSize = value; }
        }


        public override IDocumentPaginatorSource Source
        {
            get { return flowDocumentpaginator.Source; }
        }


        Rect Move(Rect rect,Size m_Margin)
        {
            if (rect.IsEmpty)
            {
                return rect;
            }
            else
            {
                return new Rect(rect.Left + m_Margin.Width, rect.Top + m_Margin.Height,
                                rect.Width, rect.Height);
            }
        }
        
public override DocumentPage GetPage(int pageNumber)
        {
            DocumentPage page = null;
            if (this != flowDocumentpaginator)
            {
                page = flowDocumentpaginator.GetPage(pageNumber);
            }
            else
            {
                page = new DocumentPage(new ContainerVisual());
            }
            // Create a wrapper visual for transformation and add extras 
            ContainerVisual newpage = new ContainerVisual();
            DrawingVisual title = new DrawingVisual();


            using (DrawingContext ctx = title.RenderOpen())
            {
                ctx.DrawRectangle(Brushes.White, null, new Rect(page.Size));
                
                    var m_Typeface = new Typeface("Arial");
                
                FormattedText text = new FormattedText("DNV Test\r\nVerIT-V test\r\n\r\ntwo stroke inline" + (pageNumber + 1),
                    System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                    m_Typeface, 14, Brushes.Black);
                ctx.DrawText(text, new Point(0, 0)); // 1/4 inch above page content 

                FormattedText text2 = new FormattedText("Nauticus Crankshaft Fatigue (beta)\r\nVersion 10.0\r\nBy DNV Software" + (pageNumber + 1).ToString(), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, m_Typeface, 14, Brushes.Black);
                ctx.DrawText(text2, new Point(page.Size.Width - 150, 10));
                var pic = new BitmapImage(new Uri("pack://application:,,,/Icon/dnv_logo.jpg", UriKind.RelativeOrAbsolute));
               ctx.DrawImage(pic, new Rect(new Point(page.Size.Width / 2, 10), new Point(page.Size.Width / 2 + pic.Width, pic.Height + 10)));

            }

            ContainerVisual smallerPage = new ContainerVisual();
            try
            {
                newpage.Children.Add(title);
                smallerPage.Children.Add(page.Visual);
                smallerPage.Transform = new MatrixTransform(0.85, 0, 0, 0.85,
                    0.05 * page.ContentBox.Width, 0.05 * page.ContentBox.Height);
                newpage.Children.Add(smallerPage);
                var m_Margin = new Size(96, 48);
                newpage.Transform = new TranslateTransform(m_Margin.Width, m_Margin.Height);
                var m_PageSize = new Size(page.Size.Width, page.Size.Height);
                return new DocumentPage(newpage, m_PageSize, Move(page.BleedBox, m_Margin), Move(page.ContentBox, m_Margin));
            }
            catch (Exception e)
            {
                return null;
            }
        } 


    }


常见的Code(创建table,支持希腊字母,Subscript,ect...):

public static void WriteText(FlowDocument flowDocument, string text, bool isBold)
        {
            var para = new Paragraph();
            Bold b = new Bold();
            b.Inlines.Add(text);
            if (isBold)
            {
                para.Inlines.Add(b);
            }
            else
            {
                para.Inlines.Add(text);
            }
            flowDocument.Blocks.Add(para);
        }

public static TableRow AddTableRow(Table table, string[] rowData)
        {
            var currentRow = new TableRow();
            table.RowGroups[0].Rows.Add(currentRow);


            foreach (var row in rowData)
            {
                currentRow.Cells.Add(new TableCell(new Paragraph(new Run(row))));
            }
            return currentRow;
        }


        public static TableRow AddTableRow(Table table, Paragraph[] rowData)
        {
            var currentRow = new TableRow();
            table.RowGroups[0].Rows.Add(currentRow);


            foreach (var row in rowData)
            {
                currentRow.Cells.Add(new TableCell(row));
            }
            return currentRow;
        }


        public static Paragraph AddTypographySymbol(string firstPart, string secondPart, FontVariants secondPartVariants)
        {
            var para = new Paragraph();
            var run = new Run(firstPart);
            para.Inlines.Add(run);
            run = new Run(secondPart);
            run.FontFamily = new System.Windows.Media.FontFamily("Palatino Linotype");
            run.Typography.Variants = secondPartVariants;
            para.Inlines.Add(run);
            return para;
        }


        public static Paragraph AddTypographySymbol(string firstPart, string secondPart, FontVariants secondPartVariants, string thirdPart)
        {
            var para = new Paragraph();
            var run = new Run(firstPart);
            para.Inlines.Add(run);
            run = new Run(secondPart);
            run.FontFamily = new System.Windows.Media.FontFamily("Palatino Linotype");
            run.Typography.Variants = secondPartVariants;
            para.Inlines.Add(run);
            run = new Run(thirdPart);
            para.Inlines.Add(run);
            return para;
        }


var inputTable = new Table();

          doc.Blocks.Add(inputTable);


                inputTable.Columns.Add(new TableColumn());
                inputTable.Columns.Add(new TableColumn());
                inputTable.Columns.Add(new TableColumn());


                // Create and add an empty TableRowGroup to hold the table's Rows.
                inputTable.RowGroups.Add(new TableRowGroup());
                var currentRow = FlowDocumentReportWapper.AddTableRow(inputTable, new[] { "Input parameter", String.Empty, string.Empty });


                // Global formatting for the title row.
                currentRow.FontStyle = FontStyles.Italic;


FlowDocumentReportWapper.AddTableRow(inputTable, new[] { FlowDocumentReportWapper.AddTypographySymbol("Outer diameter,d", "o", FontVariants.Subscript, ":"), new Paragraph(new Run(CommonData.GetFormattedValue(Dout))), new Paragraph(new Run("mm")) });


FlowDocumentReportWapper.AddTableRow(outputTable, new[] { FlowDocumentReportWapper.AddTypographySymbol("SCF, torsion α", "t", FontVariants.Subscript, ":"), new Paragraph(new Run(CommonData.GetFormattedValue(Alphat, 3))), new Paragraph(new Run("-")) });



Typography Variants Superscript and Subscript Bug with .NET 4.0

There is an odd bug that happens when using Typography Variants of Superscript and Subscript, which causes the Variant to not be implemented. It only happens when a number is in the Run with the attached property set. E.g.:

     <TextBlock FontFamily="Palatino Linotype" FontSize="30">
         x<Run Typography.Variants="Superscript">2</Run>
         x<Run Typography.Variants="Superscript">1234</Run>
         x<Run Typography.Variants="Superscript">A</Run>
         x<Run Typography.Variants="Superscript">2A</Run>
     </TextBlock>

The first 2 examples will fail, but the second 2 will be OK.

This is a known issue of WPF 4.0, and unfortunately, we did not get any workaround until now. 


标签:FlowDocument in WPF 

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。本文出自“wpf之家”,请务必保留此出处:http://www.wpf123.com

上一篇:没有了
下一篇:wpf标记中使用 Pack URI
相关评论
Copyright © 2009-2014 WPF之家(http://www.wpf123.com/) All rights reserved
 Powered by WPF之家
鄂ICP备13006396号