我正在尝试使用具有绑定的FlowDocument,以便有一个能够使用数据模型中的实际数据填充的单独模板。然后我将其转换为图像并打印或保存到硬盘上。
为了将FlowDocument的Runs与数据模型绑定,我使用了这篇文章中的代码:https://msdn.microsoft.com/en-us/magazine/dd569761.aspx
FlowDocument模板如下:
然后我加载模板并在其中设置DataContext:
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:p="clr-namespace:Labels;assembly=DataModel.Impl"
PageWidth="200" MinPageWidth="200" PageHeight="200" MinPageHeight="200">
<Section>
<Paragraph>
<p:BindableRun BoundText="{Binding Path=Text}"/>
</Paragraph>
</Section>
</FlowDocument>
BindableRun的代码:
public class BindableRun : Run
{
public static readonly DependencyProperty BoundTextProperty = DependencyProperty.Register("BoundText", typeof(string), typeof(BindableRun),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure, OnBoundTextChanged, CoerceText));
public BindableRun()
{
FlowDocumentHelpers.FixupDataContext(this);
}
private static void OnBoundTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((Run)d).Text = (string)e.NewValue;
}
private static object CoerceText(DependencyObject d, object value)
{
return value;
}
public String BoundText
{
get { return (string)GetValue(BoundTextProperty); }
set { SetValue(BoundTextProperty, value); }
}
}
然后我加载模板并在其中设置DataContext:
private class DataClass
{
public string Text { get; set; }
}
private static FlowDocument LoadFlowDocument(string path)
{
using (var xamlFile = new FileStream(path, FileMode.Open, FileAccess.Read))
{
return XamlReader.Load(xamlFile) as FlowDocument;
}
}
private static void FlowDoc2Image(FlowDocument document, DataClass dataContext, Stream imageStream)
{
var flowDocumentScrollViewer = new FlowDocumentScrollViewer
{
VerticalScrollBarVisibility = ScrollBarVisibility.Hidden,
HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden,
DataContext = dataContext
};
flowDocumentScrollViewer.Document = document;
flowDocumentScrollViewer.Measure(new Size(999999999, 999999999));
//1st pass
flowDocumentScrollViewer.Arrange(new Rect(0, 0, flowDocumentScrollViewer.ActualWidth, flowDocumentScrollViewer.ActualHeight));
//2nd pass. It's not code duplication! Do not remove!
flowDocumentScrollViewer.Arrange(new Rect(0, 0, flowDocumentScrollViewer.ActualWidth, flowDocumentScrollViewer.ActualHeight));
var bitmapRenderer =
new RenderTargetBitmap((int)flowDocumentScrollViewer.ActualWidth, (int)flowDocumentScrollViewer.ActualHeight, 96, 96, PixelFormats.Pbgra32);
bitmapRenderer.Render(flowDocumentScrollViewer);
var pngEncoder = new PngBitmapEncoder { Interlace = PngInterlaceOption.On };
pngEncoder.Frames.Add(BitmapFrame.Create(bitmapRenderer));
pngEncoder.Save(imageStream);
}
public void Test()
{
var doc = LoadFlowDocument("C:\\Experiments\\DocWithBinding.xaml");
var context = new DataClass {Text = "SomeText"};
doc.DataContext = context;
using (var imageStream = new FileStream("C:\\Experiments\\image.png", FileMode.OpenOrCreate, FileAccess.Write))
{
FlowDoc2Image(doc, context, imageStream);
}
}
但是什么也没发生。我试图在BindableRun中设置断点,以便在其值更改时触发。但我从未到达那里。更改DataContext不会影响文档。