原文:WPF界面设计技巧(11)-认知流文档 & 小议WPF的野心

流文档是WPF中的一种独特的文档承载格式,它的书写和呈现方式都很像HTML,它也几乎具备了HTML的绝大多数优势,并提供了更强的编程支持及对WPF其他元素的兼容。

直接来看代码吧,需要讲解的地方比较多,我就直接注释在代码里了,看起来更方便些:

Code
<Window x:Class="流文档.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="376" Width="540">
    <Grid>
        <Grid.Resources>
            <!--MailMail字符突出显示样式-->
            <Style x:Key="MailMailStyle" TargetType="Run">
                <Setter Property="FontFamily" Value="Nina"/>
                <Setter Property="FontWeight" Value="Bold"/>
                <Setter Property="Foreground" Value="#FFF88900"/>
            </Style>
            <!--超链接样式-->
            <Style TargetType="Hyperlink">
                <Setter Property="Foreground" Value="#209AC2"/>
                <!--清除文字修饰(去掉下划线)-->
                <Setter Property="TextBlock.TextDecorations" Value="{x:Null}"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Foreground" Value="#F27D00" />
                        <!--在鼠标悬停时显示下划线-->
                        <Setter Property="TextBlock.TextDecorations">
                            <Setter.Value>
                                <TextDecorationCollection>
                                    <TextDecoration Location="Underline"/>
                                </TextDecorationCollection>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
            <!--段落样式-->
            <Style TargetType="Paragraph">
                <Setter Property="Margin" Value="8"/>
            </Style>
        </Grid.Resources>
        <!--流文档阅读器-->
        <FlowDocumentReader>
            <!--流文档-->
            <FlowDocument Foreground="#647474">
                <!--标题,一个方形图形填充MailMail标志,后跟“简介”二字-->
                <!--Paragraph,段落,相当于HTML的<p>-->
                <Paragraph FontWeight="Bold" FontSize="18">
                    <Rectangle Fill="{StaticResource title}" Height="44" Width="190" Margin="0,0,6,0"/>简介
                </Paragraph>
                <!--内容-->
                <Paragraph>
                    <!--内嵌环绕区域-->
                    <Figure Width="160" Height="150" Padding="4" Margin="2">
                        <!--流文档内的控件容器-->
                        <BlockUIContainer>
                            <!--一个带边框的图片-->
                            <Border SnapsToDevicePixels="True" BorderThickness="1" Padding="3" BorderBrush="#999">
                              <Image Source="http://images.cnblogs.com/cnblogs_com/skyd/8.jpg" Stretch="UniformToFill" />
                            </Border>
                        </BlockUIContainer>
                    </Figure>
                    <!--Run,内联字符串,貌似和使用Span没什么区别,相当于HTML的<span>-->
                    <Run Style="{StaticResource MailMailStyle}">MailMail</Run>是一款独特的邮件发送工具,或许它独特到你从未感受过的地步,它可使你通过轻松、简单、愉快的操作完成日常邮件发送操作,当然,它肯定不是因“会发邮件”而独特,而是在于“怎么发”,相信我,你一定要自己来感受一下。
                </Paragraph>
                <Paragraph>
                    通过<Run Style="{StaticResource MailMailStyle}">MailMail</Run>,你可以达成很多你所未曾尝试的邮箱应用,如备份文件、分享音乐、分发资料、提交工作文档、群发消息等,<Run Style="{StaticResource MailMailStyle}">MailMail</Run>提供了巧妙的选项设置及完善的配置系统让你得心应手地做这些事。
                </Paragraph>
                <Paragraph>
                    当然,好东西也有坏处:<Run Style="{StaticResource MailMailStyle}">MailMail</Run>会让你的邮件服务商头大,因为他们许诺的1G、2G、5G空间可能都要被你充分利用掉。是的,你有很高几率发上瘾,就像一句老话:“一发不可收拾”。
                </Paragraph>
                <Paragraph>
                    <!--LineBreak,换行符,相当于HTML的<br/>-->
                    <LineBreak/>
                    相关网址:
                </Paragraph>
                <!--List,列表,相当于HTML的<ul>-->
                <List>
                    <!--ListItem,列表项,相当于HTML的<li>-->
                    <ListItem>
                        <Paragraph>
                            <!--Hyperlink,超链接,相当于HTML的<a>-->
                            介绍及帮助:<Hyperlink Click="Hyperlink_Click" NavigateUri="http://www.cnblogs.com/SkyD/archive/2008/08/09/1264083.html">http://www.cnblogs.com/SkyD/archive/2008/08/09/1264083.html</Hyperlink>
                        </Paragraph>
                    </ListItem>
                    <ListItem>
                        <Paragraph>
                            问题反馈及建议提交:<Hyperlink Click="Hyperlink_Click" NavigateUri="http://www.cnblogs.com/SkyD/articles/1264078.html">http://www.cnblogs.com/SkyD/articles/1264078.html</Hyperlink>
                        </Paragraph>
                    </ListItem>
                    <ListItem>
                        <Paragraph>
                            更新信息及下载:<Hyperlink Click="Hyperlink_Click" NavigateUri="http://www.cnblogs.com/SkyD/articles/1264080.html">http://www.cnblogs.com/SkyD/articles/1264080.html</Hyperlink>
                        </Paragraph>
                    </ListItem>
                </List>
            </FlowDocument>
        </FlowDocumentReader>
    </Grid>
</Window>

<Grid.Resources>部分我定义了文档的一些通用样式,这就像内嵌的CSS。Style真是无处不在,嗯,他能比CSS做更多的事,但也更复杂一些。

正文部分,我们看到很多元素都可以找到其在HTML里的对应,结合我们在HTML中的经验,这些都可以被轻松理解。

注意标题处引用的静态资源title是我在别处定义的,在这里看不到。

后台仅添加以下语句用于处理超链接点击事件,因为独立应用程序中不会自动处理它们:

Code
        private void Hyperlink_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start((sender as Hyperlink).NavigateUri.ToString());
        }

下面看看显示效果:

这是呈现出的文档浏览界面,流文档也支持被选取和复制。

我们使用的这种流文档容器拥有一些实用的内置功能,比如分页浏览,下面就是第二页的样子:

现在,把窗口拉大,测试一下流文档的变化:

它像极了HTML,这种自适应性可以让我们轻松地在多种环境下阅读。

现在对文档进行放大,可以看到,文字、图像都被放大了。这种特性同样为多环境阅览提供了有效的帮助,尤其是我们希望通过投影或屏幕展示文档时。

这是分栏阅读,可能比较适合有读书习惯的人使用吧,我是觉得没什么意义。

带滚动条的阅读方式,比较适合用在网页和桌面程序界面里。

文本搜索功能,和IE里差不多一样简陋~~

可以想象一下,在以后,我们使用一份文档就可以用于软件帮助、手册印刷、投影展示、网页呈现(支持移动设备)以及更多应用(如盲人阅读),而自始至终都不需要做任何修改或转换。

嗯,为了实现这一构想,我们从现在做起,把硬编码在程序中的流文档分离出来:

分离出的流文档文件:

Code
<!--流文档-->
<FlowDocument xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <FlowDocument.Resources>
        <!--标题图形-->
        <DrawingBrush x:Key="title" Stretch="Uniform">
            <DrawingBrush.Drawing>
                <DrawingGroup>
                    <DrawingGroup.Children>
                        <GeometryDrawing Brush="#FF959595" Geometry="F1 M 377.274,177.037L 366.042,177.037L 366.042,144.841L 359.373,165.254L 351.495,165.254L 344.826,144.841L 344.826,177.037L 334.218,177.037L 334.218,126.441L 347.605,126.441L 355.726,150.255L 363.877,126.441L 377.274,126.441L 377.274,177.037 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="6.66667" LineJoin="Round" Brush="#FF959595"/>
                            </GeometryDrawing.Pen>
                        </GeometryDrawing>
                        <GeometryDrawing Brush="#FF959595" Geometry="F1 M 404.106,167.658L 404.106,159.016C 403.17,159.175 402.172,159.394 401.113,159.672C 400.053,159.95 399.25,160.255 398.704,160.587C 398.061,160.991 397.552,161.585 397.178,162.368C 396.805,163.151 396.618,164.168 396.618,165.417C 396.618,166.825 396.904,167.958 397.476,168.817C 398.048,169.676 398.968,170.106 400.235,170.106C 400.879,170.106 401.571,169.893 402.312,169.467C 403.053,169.041 403.651,168.438 404.106,167.658 Z M 404.106,173.452C 403.456,174.167 402.897,174.782 402.429,175.299C 401.961,175.815 401.311,176.34 400.479,176.874C 399.77,177.329 398.969,177.701 398.076,177.99C 397.182,178.279 396.124,178.423 394.902,178.423C 392.406,178.423 390.3,177.302 388.584,175.06C 386.868,172.819 386.01,169.915 386.01,166.348C 386.01,163.54 386.431,161.255 387.272,159.493C 388.114,157.731 389.357,156.313 391.002,155.237C 392.588,154.212 394.554,153.481 396.901,153.044C 399.247,152.607 401.668,152.288 404.164,152.086L 404.164,151.533C 404.164,149.382 403.586,147.896 402.429,147.077C 401.272,146.257 399.514,145.848 397.154,145.848C 396.439,145.848 395.718,145.952 394.99,146.162C 394.262,146.371 393.53,146.624 392.796,146.92C 392.159,147.172 391.538,147.467 390.934,147.802C 390.329,148.138 389.822,148.411 389.413,148.62L 388.506,148.62L 388.506,139.491C 389.468,139.137 391.01,138.722 393.132,138.245C 395.255,137.769 397.385,137.531 399.523,137.531C 402.019,137.531 404.181,137.758 406.007,138.213C 407.834,138.668 409.41,139.444 410.736,140.541C 412.023,141.588 413.008,142.956 413.69,144.646C 414.373,146.335 414.714,148.422 414.714,150.905L 414.714,177.037L 404.106,177.037L 404.106,173.452 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="6.66667" LineJoin="Round" Brush="#FF959595"/>
                            </GeometryDrawing.Pen>
                        </GeometryDrawing>
                        <GeometryDrawing Brush="#FF959595" Geometry="F1 M 434.682,177.037L 424.074,177.037L 424.074,138.917L 434.682,138.917L 434.682,177.037 Z M 434.682,133.372L 424.074,133.372L 424.074,124.362L 434.682,124.362L 434.682,133.372 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="6.66667" LineJoin="Round" Brush="#FF959595"/>
                            </GeometryDrawing.Pen>
                        </GeometryDrawing>
                        <GeometryDrawing Brush="#FF959595" Geometry="F1 M 455.274,177.037L 444.666,177.037L 444.666,124.362L 455.274,124.362L 455.274,177.037 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="6.66667" LineJoin="Round" Brush="#FF959595"/>
                            </GeometryDrawing.Pen>
                        </GeometryDrawing>
                        <GeometryDrawing Brush="#FF959595" Geometry="F1 M 508.938,177.037L 497.706,177.037L 497.706,144.841L 491.037,165.254L 483.159,165.254L 476.49,144.841L 476.49,177.037L 465.882,177.037L 465.882,126.441L 479.268,126.441L 487.39,150.255L 495.541,126.441L 508.938,126.441L 508.938,177.037 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="6.66667" LineJoin="Round" Brush="#FF959595"/>
                            </GeometryDrawing.Pen>
                        </GeometryDrawing>
                        <GeometryDrawing Brush="#FF959595" Geometry="F1 M 535.769,167.658L 535.769,159.016C 534.833,159.175 533.836,159.394 532.776,159.672C 531.717,159.95 530.914,160.255 530.368,160.587C 529.724,160.991 529.216,161.585 528.842,162.368C 528.468,163.151 528.281,164.168 528.281,165.417C 528.281,166.825 528.567,167.958 529.139,168.817C 529.711,169.676 530.631,170.106 531.899,170.106C 532.542,170.106 533.234,169.893 533.975,169.467C 534.716,169.041 535.315,168.438 535.769,167.658 Z M 535.769,173.452C 535.119,174.167 534.56,174.782 534.092,175.299C 533.624,175.815 532.974,176.34 532.142,176.874C 531.434,177.329 530.633,177.701 529.739,177.99C 528.845,178.279 527.787,178.423 526.565,178.423C 524.069,178.423 521.963,177.302 520.247,175.06C 518.531,172.819 517.673,169.915 517.673,166.348C 517.673,163.54 518.094,161.255 518.936,159.493C 519.778,157.731 521.021,156.313 522.665,155.237C 524.251,154.212 526.218,153.481 528.564,153.044C 530.911,152.607 533.332,152.288 535.828,152.086L 535.828,151.533C 535.828,149.382 535.249,147.896 534.092,147.077C 532.935,146.257 531.177,145.848 528.818,145.848C 528.103,145.848 527.381,145.952 526.653,146.162C 525.925,146.371 525.194,146.624 524.459,146.92C 523.822,147.172 523.202,147.467 522.597,147.802C 521.993,148.138 521.486,148.411 521.076,148.62L 520.169,148.62L 520.169,139.491C 521.131,139.137 522.674,138.722 524.796,138.245C 526.918,137.769 529.048,137.531 531.187,137.531C 533.683,137.531 535.844,137.758 537.671,138.213C 539.497,138.668 541.073,139.444 542.399,140.541C 543.686,141.588 544.671,142.956 545.354,144.646C 546.036,146.335 546.378,148.422 546.378,150.905L 546.378,177.037L 535.769,177.037L 535.769,173.452 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="6.66667" LineJoin="Round" Brush="#FF959595"/>
                            </GeometryDrawing.Pen>
                        </GeometryDrawing>
                        <GeometryDrawing Brush="#FF959595" Geometry="F1 M 566.345,177.037L 555.737,177.037L 555.737,138.917L 566.345,138.917L 566.345,177.037 Z M 566.345,133.372L 555.737,133.372L 555.737,124.362L 566.345,124.362L 566.345,133.372 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="6.66667" LineJoin="Round" Brush="#FF959595"/>
                            </GeometryDrawing.Pen>
                        </GeometryDrawing>
                        <GeometryDrawing Brush="#FF959595" Geometry="F1 M 586.937,177.037L 576.329,177.037L 576.329,124.362L 586.937,124.362L 586.937,177.037 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="6.66667" LineJoin="Round" Brush="#FF959595"/>
                            </GeometryDrawing.Pen>
                        </GeometryDrawing>
                        <GeometryDrawing Geometry="F1 M 377.274,177.037L 366.042,177.037L 366.042,144.841L 359.373,165.255L 351.495,165.255L 344.826,144.841L 344.826,177.037L 334.218,177.037L 334.218,126.442L 347.604,126.442L 355.726,150.256L 363.877,126.442L 377.274,126.442L 377.274,177.037 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="1.33333" LineJoin="Round" Brush="#FFCF7200"/>
                            </GeometryDrawing.Pen>
                            <GeometryDrawing.Brush>
                                <LinearGradientBrush StartPoint="0.5,0.934258" EndPoint="0.5,0.00654315">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="#FFF8B057" Offset="0"/>
                                        <GradientStop Color="#FFFFD68A" Offset="1"/>
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </GeometryDrawing.Brush>
                        </GeometryDrawing>
                        <GeometryDrawing Geometry="F1 M 404.106,167.659L 404.106,159.017C 403.17,159.176 402.172,159.394 401.112,159.672C 400.053,159.95 399.25,160.255 398.704,160.587C 398.061,160.991 397.552,161.585 397.178,162.368C 396.805,163.152 396.618,164.168 396.618,165.417C 396.618,166.825 396.904,167.958 397.476,168.817C 398.048,169.677 398.967,170.106 400.235,170.106C 400.878,170.106 401.571,169.893 402.312,169.467C 403.053,169.041 403.651,168.438 404.106,167.659 Z M 404.106,173.453C 403.456,174.167 402.897,174.783 402.429,175.299C 401.961,175.815 401.311,176.34 400.479,176.875C 399.77,177.329 398.969,177.701 398.075,177.99C 397.182,178.279 396.124,178.423 394.902,178.423C 392.406,178.423 390.3,177.302 388.584,175.061C 386.868,172.819 386.01,169.915 386.01,166.348C 386.01,163.54 386.431,161.255 387.272,159.493C 388.114,157.732 389.357,156.313 391.002,155.237C 392.588,154.212 394.554,153.481 396.9,153.044C 399.247,152.607 401.668,152.288 404.164,152.086L 404.164,151.534C 404.164,149.382 403.586,147.897 402.429,147.077C 401.272,146.258 399.513,145.848 397.154,145.848C 396.439,145.848 395.717,145.953 394.989,146.162C 394.261,146.371 393.53,146.624 392.796,146.92C 392.159,147.173 391.538,147.467 390.933,147.803C 390.329,148.138 389.822,148.411 389.412,148.62L 388.506,148.62L 388.506,139.491C 389.468,139.137 391.01,138.722 393.132,138.246C 395.254,137.769 397.385,137.531 399.523,137.531C 402.019,137.531 404.18,137.758 406.007,138.213C 407.833,138.668 409.41,139.444 410.736,140.542C 412.023,141.588 413.007,142.957 413.69,144.646C 414.372,146.335 414.714,148.422 414.714,150.905L 414.714,177.037L 404.106,177.037L 404.106,173.453 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="1.33333" LineJoin="Round" Brush="#FFCF7200"/>
                            </GeometryDrawing.Pen>
                            <GeometryDrawing.Brush>
                                <LinearGradientBrush StartPoint="0.500001,0.86046" EndPoint="0.500001,0.0843549">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="#FFF8B057" Offset="0"/>
                                        <GradientStop Color="#FFFFD68A" Offset="1"/>
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </GeometryDrawing.Brush>
                        </GeometryDrawing>
                        <GeometryDrawing Geometry="F1 M 434.682,177.037L 424.074,177.037L 424.074,138.917L 434.682,138.917L 434.682,177.037 Z M 434.682,133.372L 424.074,133.372L 424.074,124.362L 434.682,124.362L 434.682,133.372 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="1.33333" LineJoin="Round" Brush="#FFCF7200"/>
                            </GeometryDrawing.Pen>
                            <GeometryDrawing.Brush>
                                <LinearGradientBrush StartPoint="0.500001,0.589712" EndPoint="0.500001,0.351091">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="#FFF8B057" Offset="0"/>
                                        <GradientStop Color="#FFFFD68A" Offset="1"/>
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </GeometryDrawing.Brush>
                        </GeometryDrawing>
                        <GeometryDrawing Geometry="F1 M 455.273,177.037L 444.665,177.037L 444.665,124.362L 455.273,124.362L 455.273,177.037 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="1.33333" LineJoin="Round" Brush="#FFCF7200"/>
                            </GeometryDrawing.Pen>
                            <GeometryDrawing.Brush>
                                <LinearGradientBrush StartPoint="0.499996,0.589712" EndPoint="0.499996,0.351091">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="#FFF8B057" Offset="0"/>
                                        <GradientStop Color="#FFFFD68A" Offset="1"/>
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </GeometryDrawing.Brush>
                        </GeometryDrawing>
                        <GeometryDrawing Geometry="F1 M 508.937,177.037L 497.705,177.037L 497.705,144.841L 491.036,165.255L 483.158,165.255L 476.489,144.841L 476.489,177.037L 465.881,177.037L 465.881,126.442L 479.268,126.442L 487.39,150.256L 495.541,126.442L 508.937,126.442L 508.937,177.037 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="1.33333" LineJoin="Round" Brush="#FFCF7200"/>
                            </GeometryDrawing.Pen>
                            <GeometryDrawing.Brush>
                                <LinearGradientBrush StartPoint="0.499999,0.934258" EndPoint="0.499999,0.00654315">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="#FFF8B057" Offset="0"/>
                                        <GradientStop Color="#FFFFD68A" Offset="1"/>
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </GeometryDrawing.Brush>
                        </GeometryDrawing>
                        <GeometryDrawing Geometry="F1 M 535.769,167.659L 535.769,159.017C 534.833,159.176 533.835,159.394 532.776,159.672C 531.716,159.95 530.914,160.255 530.368,160.587C 529.724,160.991 529.216,161.585 528.842,162.368C 528.468,163.152 528.281,164.168 528.281,165.417C 528.281,166.825 528.567,167.958 529.139,168.817C 529.711,169.677 530.631,170.106 531.898,170.106C 532.542,170.106 533.234,169.893 533.975,169.467C 534.716,169.041 535.314,168.438 535.769,167.659 Z M 535.769,173.453C 535.119,174.167 534.56,174.783 534.092,175.299C 533.624,175.815 532.974,176.34 532.142,176.875C 531.434,177.329 530.633,177.701 529.739,177.99C 528.845,178.279 527.787,178.423 526.565,178.423C 524.069,178.423 521.963,177.302 520.247,175.061C 518.531,172.819 517.673,169.915 517.673,166.348C 517.673,163.54 518.094,161.255 518.936,159.493C 519.778,157.732 521.021,156.313 522.665,155.237C 524.251,154.212 526.217,153.481 528.564,153.044C 530.91,152.607 533.332,152.288 535.828,152.086L 535.828,151.534C 535.828,149.382 535.249,147.897 534.092,147.077C 532.935,146.258 531.177,145.848 528.817,145.848C 528.102,145.848 527.381,145.953 526.653,146.162C 525.925,146.371 525.194,146.624 524.459,146.92C 523.822,147.173 523.201,147.467 522.597,147.803C 521.992,148.138 521.485,148.411 521.076,148.62L 520.169,148.62L 520.169,139.491C 521.131,139.137 522.673,138.722 524.796,138.246C 526.918,137.769 529.048,137.531 531.187,137.531C 533.683,137.531 535.844,137.758 537.67,138.213C 539.497,138.668 541.073,139.444 542.399,140.542C 543.686,141.588 544.671,142.957 545.353,144.646C 546.036,146.335 546.377,148.422 546.377,150.905L 546.377,177.037L 535.769,177.037L 535.769,173.453 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="1.33333" LineJoin="Round" Brush="#FFCF7200"/>
                            </GeometryDrawing.Pen>
                            <GeometryDrawing.Brush>
                                <LinearGradientBrush StartPoint="0.499998,0.86046" EndPoint="0.499998,0.0843549">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="#FFF8B057" Offset="0"/>
                                        <GradientStop Color="#FFFFD68A" Offset="1"/>
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </GeometryDrawing.Brush>
                        </GeometryDrawing>
                        <GeometryDrawing Geometry="F1 M 566.345,177.037L 555.737,177.037L 555.737,138.917L 566.345,138.917L 566.345,177.037 Z M 566.345,133.372L 555.737,133.372L 555.737,124.362L 566.345,124.362L 566.345,133.372 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="1.33333" LineJoin="Round" Brush="#FFCF7200"/>
                            </GeometryDrawing.Pen>
                            <GeometryDrawing.Brush>
                                <LinearGradientBrush StartPoint="0.499997,0.589712" EndPoint="0.499997,0.351091">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="#FFF8B057" Offset="0"/>
                                        <GradientStop Color="#FFFFD68A" Offset="1"/>
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </GeometryDrawing.Brush>
                        </GeometryDrawing>
                        <GeometryDrawing Geometry="F1 M 586.937,177.037L 576.329,177.037L 576.329,124.362L 586.937,124.362L 586.937,177.037 Z ">
                            <GeometryDrawing.Pen>
                                <Pen Thickness="1.33333" LineJoin="Round" Brush="#FFCF7200"/>
                            </GeometryDrawing.Pen>
                            <GeometryDrawing.Brush>
                                <LinearGradientBrush StartPoint="0.499994,0.589712" EndPoint="0.499994,0.351091">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="#FFF8B057" Offset="0"/>
                                        <GradientStop Color="#FFFFD68A" Offset="1"/>
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </GeometryDrawing.Brush>
                        </GeometryDrawing>
                    </DrawingGroup.Children>
                </DrawingGroup>
            </DrawingBrush.Drawing>
        </DrawingBrush>
        <!--MailMail字符突出显示样式-->
        <Style x:Key="MailMailStyle" TargetType="Run">
            <Setter Property="FontFamily" Value="Nina"/>
            <Setter Property="FontWeight" Value="Bold"/>
            <Setter Property="Foreground" Value="#FFF88900"/>
        </Style>
    </FlowDocument.Resources>
    <!--标题,一个方形图形填充MailMail标志,后跟“简介”二字-->
    <!--Paragraph,段落,相当于HTML的<p>-->
    <Paragraph FontWeight="Bold" FontSize="18">
        <Rectangle Fill="{StaticResource title}" Height="44" Width="190" Margin="0,0,6,0"/> 简介
    </Paragraph>
    <!--内容-->
    <Paragraph>
        <!--内嵌环绕区域-->
        <Figure Width="160" Height="150" Padding="4" Margin="2">
            <!--流文档内的控件容器-->
            <BlockUIContainer>
                <!--一个带边框的图片-->
                <Border SnapsToDevicePixels="True" BorderThickness="1" Padding="3" BorderBrush="#999">
                    <Image Source="http://images.cnblogs.com/cnblogs_com/skyd/8.jpg" Stretch="UniformToFill" />
                </Border>
            </BlockUIContainer>
        </Figure>
        <!--Run,内联字符串,貌似和使用Span没什么区别,相当于HTML的<span>-->
        <Run Style="{StaticResource MailMailStyle}">MailMail</Run> 是一款独特的邮件发送工具,或许它独特到你从未感受过的地步,它可使你通过轻松、简单、愉快的操作完成日常邮件发送操作,当然,它肯定不是因“会发邮件”而独特,而是在于“怎么发”,相信我,你一定要自己来感受一下。
    </Paragraph>
    <Paragraph>
        通过
        <Run Style="{StaticResource MailMailStyle}">MailMail</Run> ,你可以达成很多你所未曾尝试的邮箱应用,如备份文件、分享音乐、分发资料、提交工作文档、群发消息等,
        <Run Style="{StaticResource MailMailStyle}">MailMail</Run> 提供了巧妙的选项设置及完善的配置系统让你得心应手地做这些事。
    </Paragraph>
    <Paragraph>
        当然,好东西也有坏处:
        <Run Style="{StaticResource MailMailStyle}">MailMail</Run> 会让你的邮件服务商头大,因为他们许诺的1G、2G、5G空间可能都要被你充分利用掉。是的,你有很高几率发上瘾,就像一句老话:“一发不可收拾”。
    </Paragraph>
    <Paragraph>
        <!--LineBreak,换行符,相当于HTML的<br/>-->
        <LineBreak/>
        相关网址:
    </Paragraph>
    <!--List,列表,相当于HTML的<ul>-->
    <List>
        <!--ListItem,列表项,相当于HTML的<li>-->
        <ListItem>
            <Paragraph>
                <!--Hyperlink,超链接,相当于HTML的<a>-->
                介绍及帮助:<Hyperlink NavigateUri="http://www.cnblogs.com/SkyD/archive/2008/08/09/1264083.html">http://www.cnblogs.com/SkyD/archive/2008/08/09/1264083.html</Hyperlink>
            </Paragraph>
        </ListItem>
        <ListItem>
            <Paragraph>
                问题反馈及建议提交:<Hyperlink NavigateUri="http://www.cnblogs.com/SkyD/articles/1264078.html">http://www.cnblogs.com/SkyD/articles/1264078.html</Hyperlink>
            </Paragraph>
        </ListItem>
        <ListItem>
            <Paragraph>
                更新信息及下载:<Hyperlink NavigateUri="http://www.cnblogs.com/SkyD/articles/1264080.html">http://www.cnblogs.com/SkyD/articles/1264080.html</Hyperlink>
            </Paragraph>
        </ListItem>
    </List>
</FlowDocument>

很长啊,主要是因为我把之前那个标题图形资源“title”给加进来了。

我们在这里取消了超链接的事件,并且将一些通用的样式定义也取消了,因为我们要的是一个比较干净、纯粹的独立文档,通用的样式应该留给使用方去按需求定义。

一个听起来不错的消息是:它现在可以直接被IE打开并阅读了

IE也自动使用我们之前用过的流文档阅读器来呈现流文档。

接下来还要修改一下我们先前的程序,以使之能载入这个文档。

Code
<Window x:Class="流文档.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="376" Width="540">
    <Grid>
        <Grid.Resources>
            <!--超链接样式-->
            <Style TargetType="Hyperlink">
                <!--设置单击超链接的事件处理程序-->
                <EventSetter Event="Click" Handler="Hyperlink_Click"/>
                <Setter Property="Foreground" Value="#209AC2"/>
                <!--清除文字修饰(去掉下划线)-->
                <Setter Property="TextBlock.TextDecorations" Value="{x:Null}"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Foreground" Value="#F27D00" />
                        <!--在鼠标悬停时显示下划线-->
                        <Setter Property="TextBlock.TextDecorations">
                            <Setter.Value>
                                <TextDecorationCollection>
                                    <TextDecoration Location="Underline"/>
                                </TextDecorationCollection>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
            <!--段落样式-->
            <Style TargetType="Paragraph">
                <Setter Property="Margin" Value="8"/>
            </Style>
        </Grid.Resources>
        <!--流文档阅读器-->
        <FlowDocumentReader TextElement.Foreground="#647474" Loaded="FlowDocumentReader_Loaded"/>
    </Grid>
</Window>

这是修改后的前台代码。

超链接样式定义中加入了一个事件设置器,为超链接的点击事件设置为先前的处理程序。

流文档阅读器增加一个事件用于在读取后载入我们分离出去的流文档。

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Markup;
using System.IO; namespace 流文档
{
    /// <summary>
    /// Window1.xaml 的交互逻辑
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }         private void Hyperlink_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start((sender as Hyperlink).NavigateUri.ToString());
        }         private void FlowDocumentReader_Loaded(object sender, RoutedEventArgs e)
        {
            (sender as FlowDocumentReader).Document = XamlReader.Load(new FileStream("MailMailDoc.xaml", FileMode.Open)) as FlowDocument;
        }
    }
}

后台就是两个事件处理,很简单。

这样就可以完美还原到我们之前所作的效果了,为了提高感性认识,我把前面的贴图再弄过来个充数~~

总结一下,流文档技术现在还不能让人满意:应用覆盖面低,就连SilverLight都没有对其支持;没有配套编辑软件,现在手写代码是最好的编辑流文档的途径,使用RichTextBox只能进行比较简单的格式编辑,期待下一版的Office能够全力支持这一新格式。

这些问题的解决应该都只是时间问题,流文档的设计非常简约、完善,定位十分准确,相信会成为未来网络文档的主要载体。

或许有人会问,这么一个和HTML极度相似的东西有什么意义?

首先他和HTML定位不一样,至少是和HTML现在的定位不一样。我们拿到一个流文档,很明确的知道它就是一份文档;但拿到一个HTML,即使它格式再规范,我们也不确定它是什么东西,它里面可能掺杂了很多页头、页脚、导航链接、菜单、布局块、侧边栏、脚本等等,它就是个大杂烩,我们的程序并不喜欢这种不确定的东西。

HTML设计之初也就是用于呈现简单的文档,但现在日益膨胀的应用,使得它不得不自己承担起布局、美化、处理交互等等行为;而我们WPF完全不需顾虑这些,一个简单到乏味的DockPanel在2分钟内创造的布局,使用CSS+XHTML可能需要半小时甚至更多的时间才能创建并调试完成,而当我们决定重新调整布局位置时也能同样轻松的完成,换成CSS就是在经历噩梦了(是的,它以前就是这么说表格布局的,事实证明,它们都是噩梦),而Grid更是会让所有网页设计师挠墙。

所以你不会看到我去绞尽脑汁地将一个TextBlock定义为一个侧边栏,或是将一个List变为导航菜单,WPF有更精确、更适用的元素用于布局和交互,而HTML不得不靠整容来完成,那些随之产生的无语义的标记就好像垫鼻梁、盐水袋丰胸一样让我觉得恶心。

HTML现在被普遍称之为网页,是的,你闭着眼睛也能在互联网上找到很多HTML“页”,但你很难见到一份HTML“文档”。WPF的Page就是页、Window就是窗口、Document就是文档,非常清晰明确。

HTML混乱、陈旧的现状其实就是WPF的巨大机遇,这也应该就是微软的野心所向,单纯以技术能力来讲,WPF可以毫不费力的横扫HTML、Flash、AIR,其所欠缺的,就是我们的推动了。

本来还想写出流文档的编辑和输出呢,一看都2W多字了~~下次再说了~~~

源文件

WPF界面设计技巧(11)-认知流文档 & 小议WPF的野心的更多相关文章

  1. WPF界面设计技巧(1)—不规则窗体图文指南

    原文:WPF界面设计技巧(1)-不规则窗体图文指南 初到园子,奉上第一篇入门级教程,请勿见笑. 以往WinForm编程中,实现不规则窗体是有一定难度的,更难的是不规则窗体的边缘抗锯齿及局部透明处理.而 ...

  2. WPF界面设计技巧(10)-样式的继承

    原文:WPF界面设计技巧(10)-样式的继承 PS:现在我的MailMail完工了,进入内测阶段了,终于可以腾出手来写写教程了哈,关于MailMail的介绍及内测程序索取:http://www.cnb ...

  3. WPF界面设计技巧(5)—自定义列表项呈现内容

    原文:WPF界面设计技巧(5)-自定义列表项呈现内容 接续上次的程序,稍微改动一下原有样式,并添加一个数据模板,我们就可以达成下面这样的显示功能: 鼠标悬停于文件列表项上,会在工具提示中显示图像缩略图 ...

  4. WPF界面设计技巧(9)—使用UI自动化布局

    原文:WPF界面设计技巧(9)-使用UI自动化布局 最近一直没时间更新这系列文章,因为我一直在埋头编写我的第一个WPF应用程序:MailMail 今天开始编写附属的加密/解密工具,对UI自动化布局有些 ...

  5. WPF界面设计技巧(8)—自制山寨版CheckListBox

    原文:WPF界面设计技巧(8)-自制山寨版CheckListBox 近年来IT市场山寨横行啊,我们今天也来发扬一下山寨精神,搞个自制的CheckListBox出来. 喏,CheckListBox 就是 ...

  6. WPF界面设计技巧(7)—模拟电梯升降的缓动动画

    原文:WPF界面设计技巧(7)-模拟电梯升降的缓动动画 如同Flash一样,WPF的亮点之一也在于其擅于表现平滑的动画效果,但以移动动画来说,仅凭简单的起始位置.目标位置,所产生的动画仍会非常生硬,这 ...

  7. WPF界面设计技巧(6)—玩玩数字墨水手绘涂鸦

    原文:WPF界面设计技巧(6)-玩玩数字墨水手绘涂鸦 想让你的程序支持鼠标及手写笔涂鸦吗?只要敲入“<InkCanvas/>”这几个字符,你就会领悟什么叫“很好很强大”,今天我们来做一个手 ...

  8. WPF界面设计技巧(4)—自定义列表项样式

    原文:WPF界面设计技巧(4)-自定义列表项样式 有前面修改按钮样式的基础,我们可以尝试来定制一个即好看又好用的 ListBox ,今天先来讲“好看”部分. 打开 Microsoft Visual S ...

  9. WPF界面设计技巧(3)—实现不规则动画按钮

    原文:WPF界面设计技巧(3)-实现不规则动画按钮 发布了定义WPF按钮的教程后,有朋友问能否实现不规则形状的按钮,今天我们就来讲一下不规则按钮的制作. 不规则按钮的做法实际上和先前我们做不规则窗体的 ...

随机推荐

  1. 简易的sniffer程序

    真的非常简易,这个程序不过抓一些发送到本机的数据包,然后显示出来它们的一些信息罢了.      程序很easy!       #include <WinSock2.h> #include ...

  2. 使用datapump 导出导入同义词(export and import synonym using datapump)

    对于同义词的备份我们有多种方式来实现,如直接通过脚本生成同义词的创建脚本,或者使用dbms_metadata.get_ddl来提取同义词的定义脚本.然而在使用传统的exp或是datapump expd ...

  3. 怎样写Makefile文件(C语言部分)

    本文摘抄自"跟我一起写Makefile ",只是原文中我自己感觉比较精要的一部分,并且只针对C语言,使用GCC编译器. 原文请看这里:http://wiki.ubuntu.org. ...

  4. 大数据实时处理-基于Spark的大数据实时处理及应用技术培训

    随着互联网.移动互联网和物联网的发展,我们已经切实地迎来了一个大数据 的时代.大数据是指无法在一定时间内用常规软件工具对其内容进行抓取.管理和处理的数据集合,对大数据的分析已经成为一个非常重要且紧迫的 ...

  5. autotools入门笔记(一)

    GNU autotools作用:收集系统配置信息并自动生成Makefile文件. GNU autotools主要包括三个工具:autoconf.automake.libtool,还有很多辅助的工具,包 ...

  6. alv 列标题

    gs_fieldcat-reptext_ddic才是显示列标题的

  7. HDU 4166 & BNU 32715 Robot Navigation (记忆化bfs)

    题意:给一个二维地图,每个点为障碍或者空地,有一个机器人有三种操作:1.向前走:2.左转90度:3.右转90度.现给定起点和终点,问到达终点最短路的条数. 思路:一般的题目只是求最短路的长度,但本题还 ...

  8. 14.2.5.2 Clustered and Secondary Indexes

    14.2.5.2 Clustered and Secondary Indexes : 每个InnoDB 表 有一个特别的索引称为clustered index 行数据存储的地方. 典型的,cluste ...

  9. phpStorm 新建文件SVN不提交的解决的方法

    phpStorm中新建文件夹,可是打开文件夹.却没有提交到SVN.导致每次都必须手动增加.假设新增的文件夹或者文件较多文件夹较深,easy遗漏.(default7#zbphp.com) 解决的方法: ...

  10. 玩转Windows服务系列——服务运行、停止流程浅析

    原文:玩转Windows服务系列——服务运行.停止流程浅析 通过研究Windows服务注册卸载的原理,感觉它并没有什么特别复杂的东西,Windows服务正在一步步退去它那神秘的面纱,至于是不是美女,大 ...