문제

FlowDocument가 XPS 문서로 저장 될 때 표시하기 위해 FlowDocument에 이미지를 포함하는 데 어려움이 있습니다.

여기에 내가하는 일이 있습니다.

  1. The를 사용하여 이미지를 만듭니다 영상 WPF의 제어. 시작/endinit로 호출로 괄호로 만든 이미지 소스를 설정했습니다.
  2. FlowDocument에 이미지를 래핑하는 데 이미지를 추가하십시오. Blockuicontainer.
  3. 수정 된 버전을 사용하여 FlowDocument 객체를 XPS 파일에 저장합니다. 이 코드.

그런 다음 XPS 뷰어에서 저장된 파일을 보면 이미지가 표시되지 않습니다. 문제는 WPF가 화면에 실제로 표시 될 때까지 이미지가로드되지 않으므로 XPS 파일에 저장되지 않는다는 것입니다. 따라서 해결 방법이 있습니다. 처음으로 화면에 문서를 표시하면 FlowDocumentPageViewer 그런 다음 XPS 파일을 저장하면 이미지가로드되어 XPS 파일에 나타납니다. FlowDocumentPageViewer가 숨겨져 있어도 작동합니다. 그러나 그것은 나에게 또 다른 도전을 준다. 다음은 (의사 코드에서) 내가하고 싶은 일은 다음과 같습니다.

void SaveDocument()
{
    AddFlowDocumentToFlowDocumentPageViewer();
    SaveFlowDocumentToXpsFile();
}

FlowDocumentPageViewer는 문서가 XPS 파일에 저장되기 전에 내용을 표시 할 기회를 얻지 못하기 때문에 물론 작동하지 않습니다. Dispatcher.BeginInvoke 호출에서 SaveFlowDocumentToxpsFile을 래핑하려고했지만 도움이되지 않았습니다.

내 질문은 다음과 같습니다.

  1. 실제로 화면에 문서를 표시하지 않고 XPS 파일을 저장하기 전에 이미지를로드 할 수 있습니까? (나는 피고를 시도했다 bitmapimage.createoptions 운이 없어).
  2. 질문 #1에 대한 해결책이 없다면 FlowDocumentPageViewer가 XPS 파일을 만들기 위해 저장 될 때를 알 수 있도록 FlowDocumentPageViewer가 내용로드를 완료했는지 알 수있는 방법이 있습니까?
도움이 되었습니까?

해결책

최종 솔루션은 당신이 온 것과 동일했으며, 이는 문서를 시청자에 넣고 간단히 화면에 표시하는 것입니다. 아래는 내가 이것을 위해 쓴 도우미 방법입니다.

private static string ForceRenderFlowDocumentXaml = 
@"<Window xmlns=""http://schemas.microsoft.com/netfx/2007/xaml/presentation""
          xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
       <FlowDocumentScrollViewer Name=""viewer""/>
  </Window>";

public static void ForceRenderFlowDocument(FlowDocument document)
{
    using (var reader = new XmlTextReader(new StringReader(ForceRenderFlowDocumentXaml)))
    {
        Window window = XamlReader.Load(reader) as Window;
        FlowDocumentScrollViewer viewer = LogicalTreeHelper.FindLogicalNode(window, "viewer") as FlowDocumentScrollViewer;
        viewer.Document = document;
        // Show the window way off-screen
        window.WindowStartupLocation = WindowStartupLocation.Manual;
        window.Top = Int32.MaxValue;
        window.Left = Int32.MaxValue;
        window.ShowInTaskbar = false;
        window.Show();
        // Ensure that dispatcher has done the layout and render passes
        Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Loaded, new Action(() => {}));
        viewer.Document = null;
        window.Close();
    }
}

편집하다: 방금 추가했습니다 window.ShowInTaskbar = false 마치 마치 마치 마치 마치 마치 작업 표시 줄에 창이 나타나는 것을 볼 수 있습니다.

사용자는 화면 밖에 위치하는 방식으로 창을 "보지"않습니다. Int32.MaxValue - 초기 멀티미디어 저자 (예 : 매크로 미디어/어도비 감독)와 함께 오늘날에 흔한 트릭.

이 질문을 찾고 찾는 사람들에게 다른 방법은 없습니다 문서를 렌더링하도록 강요합니다.

HTH,

다른 팁

몇 가지 ... 이미지가 쓰기 전에 크기가 있다고 확신합니까? 일반적으로 컨트롤에서 측정 값을 호출하여 그에 따라 크기가 크기가 될 수 있습니다 (인피니티는 컨트롤이 너비와 높이로 확장 할 수 있습니다).

image.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

또한 때로는 모든 것이 컨트롤에서 업데이트되도록 UI 스레드를 부딪 히야합니다.

Dispatcher.Invoke(DispatcherPriority.Render, new Action(() =>{}));

XPS에 이미지를 저장하려면 문서를 표시 할 필요가 없습니다. XpsSerializationManager에서 Commit을 부르고 있습니까?

FlowDocument fd = new FlowDocument();

        fd.Blocks.Add(new Paragraph(new Run("This is a test")));

        string image = @"STRING_PATH";

        BitmapImage bi = new BitmapImage();
        bi.BeginInit();
        bi.UriSource = new Uri(image, UriKind.RelativeOrAbsolute);
        bi.CacheOption = BitmapCacheOption.OnLoad;
        bi.EndInit();
        MemoryStream ms = new MemoryStream();
        Package pkg = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite);
        Uri pkgUri = bi.UriSource;

        PackageStore.AddPackage(pkgUri, pkg);


        Image img = new Image();
        img.Source = bi;

        BlockUIContainer blkContainer = new BlockUIContainer(img);

        fd.Blocks.Add(blkContainer);


        DocumentPaginator paginator = ((IDocumentPaginatorSource)fd).DocumentPaginator;

      using (XpsDocument xps = new XpsDocument(@"STRING PATH WHERE TO SAVE FILE", FileAccess.ReadWrite, CompressionOption.Maximum))
        {
            using (XpsSerializationManager serializer = new XpsSerializationManager(new XpsPackagingPolicy(xps), false))
            {
                serializer.SaveAsXaml(paginator);
                serializer.Commit();
            }
        }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top