none
FlowDocumentPageViewerにて、画面起動時に1ページ目を表示させる方法 RRS feed

  • 質問


  • どうしてもわかりませんので、ご存じの方がいればおしえてください。

    実現したいこと

     FlowPageDocumentViewerを利用して、10ページほどある文章を表示させています。

     画面起動時に、最初の1ページ目を表示させたいです。

     デフォルトでは、最後の10ページ目が表示されます。

     どのようにすれば、ページが全て生成したオブジェクトにアクセスできるのでしょうか?

    以下の方法を試してみましたが、うまくいきませんでした。

    ・イベントを利用する方法

     WindowやFlowPageDocumentViewerのLoadedTargetUpdatedイベント時に、

      FlowDocumentViewer.FirstPage()を実行してみましたが、

      WindowのLoadedイベント実行時に、FlowDocumentPage.Countを確認すると1ページ、

      FlowPageDocumentViewerのLoadedイベント実行時に、FlowDocumentPage.Countを確認すると0ページとなっていました。




    • 編集済み sasagaki 2014年2月8日 8:57
    2014年2月8日 5:52

回答

  • VS2013 Update1で.NET 4.5.1をターゲットに以下のようなWPFアプリ書いてみたのですが実行すると1ページ目が出ました。

    <Window x:Class="WpfApplication3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <FlowDocumentPageViewer>
                <FlowDocument>
                    <Paragraph>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Paragraph>
                    <Paragraph>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Paragraph>
                    <Paragraph>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Paragraph>
        <!-- 延々と続く -->
                    <Paragraph>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Paragraph>
                </FlowDocument>
            </FlowDocumentPageViewer>
        </Grid>
    </Window>
    
    なにか違うんですかね~?

    かずき Blog:http://d.hatena.ne.jp/okazuki/

    • 回答としてマーク sasagaki 2014年2月12日 2:22
    2014年2月9日 9:54
  • 再現できませんでした。むしろ最終ページを表示する方がめんどくさいです。
    それでも最終ページが表示されてしまうならば、1ページ目の要素が表示されるようにBringIntoViewしてみるとか。

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.viewer.Loaded += new RoutedEventHandler(viewer_Loaded);
    
        }
    
        void viewer_Loaded(object sender, RoutedEventArgs e)
        {
            FlowDocument doc = new FlowDocument();
            Paragraph para = new Paragraph();
            for (int j = 0; j < 10; j++)
            {
                for (int i = 0; i < 1000; i++)
                {
                    para.Inlines.Add(new Run(i.ToString()));
                }
                para.Inlines.Add(new LineBreak());
                doc.Blocks.Add(para);
    
                BlockUIContainer con = new BlockUIContainer();
                Grid grid = new Grid() { Background = Brushes.Red };
                con.Child = grid;
                doc.Blocks.Add(con);
            }
            this.viewer.Document = doc;
            GoLast();
        }
        private void GoFirst()
        {
            //先頭に移動
            FlowDocument doc = viewer.Document as FlowDocument;
            var dFirst = doc.Blocks.FirstBlock.ElementStart.GetAdjacentElement(LogicalDirection.Forward);
            if (dFirst is FrameworkContentElement)
            {
                ((FrameworkContentElement)dFirst).BringIntoView();
            }
            if (dFirst is FrameworkElement)
            {
                ((FrameworkElement)dFirst).BringIntoView();
            }
        }
        private void GoLast()
        {
            //末尾に移動
            FlowDocument doc = viewer.Document as FlowDocument;
            var dLast = doc.Blocks.LastBlock.ElementEnd.GetAdjacentElement(LogicalDirection.Backward);
            if (dLast is FrameworkContentElement)
            {
                ((FrameworkContentElement)dLast).BringIntoView();
            }
            if (dLast is FrameworkElement)
            {
                ((FrameworkElement)dLast).BringIntoView();
            }
        }
    }
    #FlowDocumentだと最終ページを表示するには全ページのレイアウトを確定する必要があるので、わざわざ重くなるのに最終ページを表示するのをデフォルトにしているとは思えないんですが。

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク sasagaki 2014年2月12日 2:22
    2014年2月9日 17:08
  • 以下が参考になるかもしれません。

    FlowDocumentPageViewer defaults to last page?
    http://social.msdn.microsoft.com/Forums/vstudio/en-US/31346a75-eb6b-4072-90fa-ceb83f7cc5e2/flowdocumentpageviewer-defaults-to-last-page?forum=wpf


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク sasagaki 2014年2月12日 2:22
    2014年2月10日 1:35
    モデレータ

すべての返信

  • VS2013 Update1で.NET 4.5.1をターゲットに以下のようなWPFアプリ書いてみたのですが実行すると1ページ目が出ました。

    <Window x:Class="WpfApplication3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <FlowDocumentPageViewer>
                <FlowDocument>
                    <Paragraph>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Paragraph>
                    <Paragraph>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Paragraph>
                    <Paragraph>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Paragraph>
        <!-- 延々と続く -->
                    <Paragraph>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Paragraph>
                </FlowDocument>
            </FlowDocumentPageViewer>
        </Grid>
    </Window>
    
    なにか違うんですかね~?

    かずき Blog:http://d.hatena.ne.jp/okazuki/

    • 回答としてマーク sasagaki 2014年2月12日 2:22
    2014年2月9日 9:54
  • 再現できませんでした。むしろ最終ページを表示する方がめんどくさいです。
    それでも最終ページが表示されてしまうならば、1ページ目の要素が表示されるようにBringIntoViewしてみるとか。

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.viewer.Loaded += new RoutedEventHandler(viewer_Loaded);
    
        }
    
        void viewer_Loaded(object sender, RoutedEventArgs e)
        {
            FlowDocument doc = new FlowDocument();
            Paragraph para = new Paragraph();
            for (int j = 0; j < 10; j++)
            {
                for (int i = 0; i < 1000; i++)
                {
                    para.Inlines.Add(new Run(i.ToString()));
                }
                para.Inlines.Add(new LineBreak());
                doc.Blocks.Add(para);
    
                BlockUIContainer con = new BlockUIContainer();
                Grid grid = new Grid() { Background = Brushes.Red };
                con.Child = grid;
                doc.Blocks.Add(con);
            }
            this.viewer.Document = doc;
            GoLast();
        }
        private void GoFirst()
        {
            //先頭に移動
            FlowDocument doc = viewer.Document as FlowDocument;
            var dFirst = doc.Blocks.FirstBlock.ElementStart.GetAdjacentElement(LogicalDirection.Forward);
            if (dFirst is FrameworkContentElement)
            {
                ((FrameworkContentElement)dFirst).BringIntoView();
            }
            if (dFirst is FrameworkElement)
            {
                ((FrameworkElement)dFirst).BringIntoView();
            }
        }
        private void GoLast()
        {
            //末尾に移動
            FlowDocument doc = viewer.Document as FlowDocument;
            var dLast = doc.Blocks.LastBlock.ElementEnd.GetAdjacentElement(LogicalDirection.Backward);
            if (dLast is FrameworkContentElement)
            {
                ((FrameworkContentElement)dLast).BringIntoView();
            }
            if (dLast is FrameworkElement)
            {
                ((FrameworkElement)dLast).BringIntoView();
            }
        }
    }
    #FlowDocumentだと最終ページを表示するには全ページのレイアウトを確定する必要があるので、わざわざ重くなるのに最終ページを表示するのをデフォルトにしているとは思えないんですが。

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク sasagaki 2014年2月12日 2:22
    2014年2月9日 17:08
  • 以下が参考になるかもしれません。

    FlowDocumentPageViewer defaults to last page?
    http://social.msdn.microsoft.com/Forums/vstudio/en-US/31346a75-eb6b-4072-90fa-ceb83f7cc5e2/flowdocumentpageviewer-defaults-to-last-page?forum=wpf


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク sasagaki 2014年2月12日 2:22
    2014年2月10日 1:35
    モデレータ
  • 体調不良のため、回答が遅れてしまい誠に申し訳ありませんでした。

    かずき様

     テスト用のXAMLを作成して検証頂きありがとうございました。

     私が利用している環境は、VS2012です。

     かずきさんが記載くださったXAMLを試してみましたが、やはり最後のページが表示されました。

     別のマシンで、VS2013をインストールして、かずきさんのXAMLを実行したところ、最初のページが表示されました。

     私が利用している環境が、どこかおかしくなっているのかもしれません。

     別のマシンにVS2012をインストールして、かずきさんが作成してくださったXAMLをテストしたいと思います。

    gekka様

     ご回答ありがとうございました。

     また、再現テストをしてくださりありがとうございます。

     BringIntoViewメソッドを利用したところ、上手く先頭ページを表示させることができました。

     DocumentPageViewerのイベントからFirstPageメソッドを利用しようとしていたのですが、どうもページが確定する前の情報にしかアクセスできないようです。

     ありがとうございました。

    trapemiya

     情報提供して頂きありがとうございました。

     頂いた情報の通り、Anchorとして空白の行を先頭に追加すると、最初のページが表示されました。

     同じ現象で悩まれている方が海外におられたようで・・・

      環境の問題なのかどうか、原因がよくわからないのですが、ありがとうございました。

     

     


    • 編集済み sasagaki 2014年2月12日 2:25
    2014年2月12日 2:22
  • かずき様

     別のマシンにVS2012をインストールして、作成して頂いたXAMLを試したところ、

     先頭ページが表示されました。

     何が影響しているか明確につかめていないのですが、私の環境が悪いようです。

     ありがとうございました。



    • 編集済み sasagaki 2014年2月13日 1:48
    2014年2月13日 1:47
  • あくまで推測に過ぎませんが、今回の現象がグラフィックドライバに起因している可能性も考えられます。グラフィックドライバを最新に更新してみてはいかがでしょうか?

    もしドライバーを更新して正常動作したなら、ビデオカードの種類とドライバーのバージョンを教えて頂けると有難いです。


    ひらぽん http://d.hatena.ne.jp/hilapon/

    2014年2月13日 5:19
    モデレータ
  • ひらぽん様

     お世話になります。

     ご連絡ありがとうございました。

     また、連絡が遅くなり、申し訳ありません。

     グラフィックドライバのバージョンを最新にあげてみましたが、結果は変わりませんでした。

     ビデオカードの種類は、NVIDIA Quadro 2000になります。

     ドライバーのバージョンは、ver306.79 WHQLになります。

      確かに、VisualStudioの他にも色々なソフトをインストールしているので、

      環境が影響しているとなると、何とも言えないところなのですが・・・


    • 編集済み sasagaki 2014年2月19日 5:56
    2014年2月19日 5:55