Printing flowdocument adds border to table - wpf

I am building flowdocument from ViewModel and then print it to pdf.
<UserControl x:Class="WpfApplication5.View.TransferTemplate" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:p="clr-namespace:WpfApplication5.Properties" xmlns:viewmodels="clr-namespace:WpfApplication5.ViewModels" d:DataContext="{d:DesignInstance Type=viewmodels:WarehouseActionViewModel}" mc:Ignorable="d"
x:Name="templ">
<FlowDocument FontFamily="Cambria" FontSize="14" Background="White" x:Name="doc" d:ColumnWidth="1024">
<Paragraph>
<Run>Date: </Run>
<Run Text="{Binding Action.ActionDate, StringFormat=dd-MM-yyyy}" />
</Paragraph>
<Paragraph>
<Run>Note: </Run>
<Run Text="{Binding Action.Note}" />
</Paragraph>
<Paragraph>
<Run>Sender: </Run>
<Run Text="{Binding Action.WarehouseFrom}" />
</Paragraph>
<Paragraph>
<Run>Receiver: </Run>
<Run Text="{Binding Action.WarehouseTo}" />
</Paragraph>
<Table x:Name="border" CellSpacing="0" BorderThickness="0" Background="{StaticResource WhiteBg}" BorderBrush="{StaticResource WhiteBg}">
<Table.Columns>
<TableColumn Width="0.2*" />
<TableColumn Width="0.7*" />
<TableColumn Width="0.1*" />
</Table.Columns>
<TableRowGroup>
<TableRow FontSize="16">
<TableCell BorderThickness="0,1,0,1" BorderBrush="#CCCCCC" Padding="5">
<Paragraph>
<Run Text="{x:Static p:Resources.barcode}" d:Text="Code" />
</Paragraph>
</TableCell>
<TableCell BorderThickness="0,1,0,1" BorderBrush="#CCCCCC" Padding="5">
<Paragraph>
<Run Text="{x:Static p:Resources.Name}" d:Text="Name" />
</Paragraph>
</TableCell>
<TableCell BorderThickness="0,1,0,1" BorderBrush="#CCCCCC" Padding="5">
<Paragraph>
<Run Text="{x:Static p:Resources.quantity}" d:Text="Quantity" />
</Paragraph>
</TableCell>
</TableRow>
<TableRow/>
</TableRowGroup>
</Table>
</FlowDocument>
</UserControl>
PrintDialog printDlg = new PrintDialog();
FlowDocument f = new TransferTemplate(vm).doc;
f.ColumnWidth = printDlg.PrintableAreaWidth;
IDocumentPaginatorSource dps = f;
if ((bool)printDlg.ShowDialog())
{
printDlg.PrintDocument(dps.DocumentPaginator, "flow doc");
}
The problem is when I create it from template and print it adds black border to table
(border thickness is set to 0)
[![enter image description here][1]][1]
but when I create document without xaml template with same code in c# it does not add border
(border thickness not set)
var table1 = new Table
{
CellSpacing = 0,
Background = Brushes.White
};
flowDoc.Blocks.Add(table1);
enter code here
[![enter image description here][2]][2]
How can I fix XAML template to disable border?
[1]: https://i.stack.imgur.com/BlYhX.png
[2]: https://i.stack.imgur.com/HoZnF.png

Just removed x:Name from the table and it worked!
Tip: Adding the Name property to any of the Flowdocument block elements adds a black border when printing (I only tested printing to PDF).

Related

How to change the stringformat of Oxyplot track value?

If I change the stringformat of axis, it works for the axis (see the black circle of the picture). But how can I change the stringformat of the track value (the red circle)?
I'd like to answer my own question based on Ramin's hint to me.
I dug into the source code a little bit, and found out there is a TrackerFormatString that I can change:
<oxy:LineSeries TrackerFormatString="{}{0}
{1}: {2:0.0}
{3}: {4:0.0}"/>
Please note the
in my code, that how a newline char is input in XAML.
Please also note the {} in the very beginning, that's kind of escape char in XAML.
if in c#, it's just:
{0}\n{1}: {2:0.0}\n{3}: {4:0.0}
You should set DefaultTrackerTemplate. Here a small example that shows you the way:
<Grid>
<oxy:Plot Title="AAA">
<oxy:Plot.Axes>
<oxy:LinearAxis Position="Left" Title="Left: " />
<oxy:LinearAxis Position="Bottom" Title="Bottom: " />
</oxy:Plot.Axes>
<oxy:Plot.Series>
<oxy:LineSeries x:Name="ls" ItemsSource="{Binding Points}"/>
</oxy:Plot.Series>
<oxy:Plot.DefaultTrackerTemplate>
<ControlTemplate>
<oxy:TrackerControl Position="{Binding Position}"
BorderThickness="1">
<oxy:TrackerControl.Content>
<StackPanel >
<DockPanel>
<TextBlock Text="{Binding XAxis.Title}" Foreground="Red" />
<TextBlock DockPanel.Dock="Right" Text="{Binding DataPoint.X}" Foreground="Red" />
</DockPanel>
<DockPanel>
<TextBlock Text="{Binding YAxis.Title}" Foreground="Green" />
<TextBlock DockPanel.Dock="Right" Text="{Binding DataPoint.Y}" Foreground="Green"
FontWeight="Bold" />
</DockPanel>
</StackPanel>
</oxy:TrackerControl.Content>
</oxy:TrackerControl>
</ControlTemplate>
</oxy:Plot.DefaultTrackerTemplate>
</oxy:Plot>
</Grid>
Hope it helps.

How to Set inline Images Vertically Center in RichTextBox

I am working on WPF, i am display RichText data in RichTextBox for that have taken WindowsFormHost, inside that i am taking WinForm RichTextBox to display RichTextData which have Images + Text.
But while display that RichTextData images are align to Top and text are align to Bottom,
See in Image below, red circle is RichTextImage
i want to display images and Text in center. Like Below Image, the Red Circle is RichTextImage that is coming in center with text.
My XAML Code is:
<Window x:Class="WPFRichTextBox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="MainWindow" Height="600" Width="800" Background="LightBlue" xmlns:my="clr-namespace:WPFRichTextBox">
<Grid Loaded="Grid_Loaded">
<WindowsFormsHost Margin="0,424,0,22">
<wf:RichTextBox Text="RichTextBox" x:Name="richTbTest1" BorderStyle="None" Enabled="True" ForeColor="Black" Width="550" Multiline="True" />
</WindowsFormsHost>
</Grid>
</Window>
I have used WPF RichTextBox also, but in that also i am not able to Align text+Images in Center
<RichTextBox VerticalContentAlignment="Stretch" Height="158" HorizontalAlignment="Left" Margin="10,247,0,0" Name="richTextBox1" VerticalAlignment="Top" Width="754" />
You can use BaselineAlignment on a Run to center align the text. Here is an example:
<RichTextBox>
<FlowDocument>
<Paragraph>
<Run Text="Some text" BaselineAlignment="Center"/>
<Image Height="100" Width="100" Source="Images\Desert.jpg"/>
<Run Text="Some more text" BaselineAlignment="Center"/>
</Paragraph>
<Paragraph/>
<Paragraph>
<Run Text="Paragraph 2" BaselineAlignment="Center"/>
<Image Height="100" Width="100" Source="Images\Desert.jpg"/>
<Run Text="More text" BaselineAlignment="Center"/>
</Paragraph>
</FlowDocument>
</RichTextBox>
EDIT:
To apply the formatting to the entire RichTextBox try calling this method after the RichTextBox is populated:
public void CenterText()
{
var text = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);
text.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Center);
}
I was able to get this working with a Span with the BaseAlignment attribute set to "Center".
<RichTextBox>
<FlowDocument>
<Paragraph>
<Span BaseAlignment="Center">
Center My Image
<Image ... />
</Span>
</Paragraph>
</FlowDocument>
</RichTextBox>

Scrolling a FlowDocument inside a TabControl

I have this XAML fragment:
<!-- ... -->
<TabControl>
<TabItem>
<!-- ... -->
</TabItem>
<TabItem Header="Source" ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.CanContentScroll="True">
<FlowDocumentScrollViewer>
<FlowDocument>
<Paragraph>
<TextBlock
Text="{Binding Path=CurrentObject.Source}"
FontFamily="Consolas,Courier,Segoe UI"
FontSize="12"
/>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
</TabItem>
</TabControl>
<!-- ... -->
The problem is that the flow document does not scroll horizontally. I've been unable to enable that.
Any clues?
Thanks in advance.
There are a couple things here. The first being that using a control in the Paragraph functions differently than a Run that would wrap to fit your FlowDocument.
The second is that the FlowDocument will fit your FlowDocumentScrollViewer. If you add a control to it like you did, it will fit the width of the FlowDocument and viewer and the text will go beyond the TextBlock borders. This means that your document doesn't need a scroll bar; your TextBlock would. You can see this by setting the TextWrapping property of the TextBlock to Wrap.
To get around this, set the PageWidth to something beyond the limits of the viewer width like so:
<FlowDocumentScrollViewer>
<FlowDocument PageHeight="1056"
PageWidth="816">
<Paragraph>
<TextBlock
Text="{Binding Path=CurrentObject.Source}"
FontFamily="Consolas,Courier,Segoe UI"
FontSize="12"
/>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
or bind to your TextBlock:
<FlowDocumentScrollViewer>
<FlowDocument PageHeight="1056"
PageWidth="{Binding ElementName=Part, Path=ActualWidth}">
<Paragraph>
<TextBlock
Text="{Binding Path=CurrentObject.Source}"
FontFamily="Consolas,Courier,Segoe UI"
FontSize="12"
/>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
The last thing is that the FlowDocumentScrollViewer has it's own HorizontalScrollBarVisibility property that you can use for this (unless some styling issue prevents it).

How to align the bottom edge of multiple TextBlocks with different FontSize

Here is the XAML sample:
<StackPanel Orientation="Horizontal" >
<TextBlock VerticalAlignment="Bottom" Text="Text1" FontSize="20" />
<Image VerticalAlignment="Bottom" ... />
<TextBlock VerticalAlignment="Bottom" Text="Text2" />
</StackPanel>
The result is that the textblocks have different bottom-margins depending on their FontSizes, but I need them all to be on one bottom line with no margins. How to get it? In my case I cant use TextBlock + Runs.
Forget several blobks : the bottom position dépends of the font size.
But, in a single paragraph, write the flow of your objects
You should use something like this :
<RichTextBlock>
<Paragraph>
<Span FontSize="148">Hello</Span>
<InlineUIContainer>
<Image Source="Assets/Logo.png"></Image>
</InlineUIContainer>
<Span FontSize="36">again</Span>
</Paragraph>
</RichTextBlock>

Databinding lost when printing data-bound FlowDocument

I'm losing data-bind when initiating a printing process, is that possible ? Thats what I can only think of in my situation here, where I have a Table inside a control that makes the Table data-bindable, all inside a FlowDocument. When running it the data-bind works fine and the table draws itself with some data on it with no problems.
However, when printing the output of that control is always blank.
I've added a ListView with the same bindings and when printing the generated data it too appears lost.
XAML:
<Window x:Class="GlassStore.InitBill"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GlassStore.ViewModels"
xmlns:flowdocs="clr-namespace:FlowDocuments;assembly=FlowDocument"
Title="InitBill" Height="825" Width="1004">
<Window.DataContext>
<local:InitBillViewModel/>
</Window.DataContext>
<Grid Background="White">
<FlowDocumentReader HorizontalAlignment="Center"
HorizontalContentAlignment="Center">
<FlowDocument ColumnWidth="999999"
IsColumnWidthFlexible="True"
TextAlignment="Center"
Name="FD">
<Paragraph>
<ListView ItemsSource="{Binding GridTrans}">
<ListView.View>
<GridView>
<GridViewColumn Header="ffff"
DisplayMemberBinding="{Binding CarModel}" />
<GridViewColumn Header="xxxx"
DisplayMemberBinding="{Binding CarName}" />
</GridView>
</ListView.View>
</ListView>
</Paragraph>
<Paragraph TextAlignment="Center">
<TextBlock Text="{Binding test}" />
</Paragraph>
<flowdocs:ItemsContent ItemsSource="{Binding GridTrans}"
Background="#FFF2C3C3"
BorderThickness="2">
<flowdocs:ItemsContent.ItemTemplate>
<DataTemplate>
<flowdocs:Fragment>
<Table>
<TableRowGroup flowdocs:Attached.IsItemsHost="True">
<TableRow Background="AliceBlue" >
<TableCell Foreground="Red">
<Paragraph>
<flowdocs:BindableRun BoundText="{Binding CarName}" />
</Paragraph>
</TableCell>
<TableCell Foreground="Green">
<Paragraph>
<flowdocs:BindableRun BoundText="{Binding CarModel}" />
</Paragraph>
</TableCell>
<TableCell Foreground="Yellow">
<Paragraph>
<flowdocs:BindableRun BoundText="{Binding glassPrice}" />
</Paragraph>
</TableCell>
</TableRow>
</TableRowGroup>
</Table>
</flowdocs:Fragment>
</DataTemplate>
</flowdocs:ItemsContent.ItemTemplate>
</flowdocs:ItemsContent>
<Table>
<TableRowGroup>
<TableRow>
<TableCell>
<Paragraph>Row1 Cell1</Paragraph>
</TableCell>
<TableCell>
<Paragraph>Row2 Cell2</Paragraph>
</TableCell>
</TableRow>
</TableRowGroup>
</Table>
</FlowDocument>
</FlowDocumentReader>
<Button Command="{Binding print}"
Content="إطـبع"
Height="29" Margin="91,0,112,41"
Name="button1"
VerticalAlignment="Bottom" />
</Grid>
</Window>
Now I know the problem is not with the Custom Control, because I have the same problem now with ListView.
I've attached the source to the Window version here and the printed version here.
The ViewModel would be nice, especially the method behind the print command. My guess ist, that the flowdocument is put into a special print context and loses the datacontext of the window.
Try removing
<Window.DataContext>
<local:InitBillViewModel/>
</Window.DataContext>
and use
<FlowDocumentReader HorizontalAlignment="Center" HorizontalContentAlignment="Center">
<FlowDocumentReader.DataContext>
<local:InitBillViewModel/>
</FlowDocumentReader.DataContext>
...
instead. Maybe that helps?
Edit: The print command would have to move to another ViewModel to still work, of course. This other ViewModel would stay where the old one was, in the Window.DataContext.
Here's my solution:
define the document in a separate XAML file:
Load the Flow Document from Resource Dictionary Xaml
then print:
var prntDlg = new PrintDialog();
var res = Application.LoadComponent(new Uri("/Resources/ReportDocument.xaml", UriKind.RelativeOrAbsolute)) as ResourceDictionary;
var doc = res["ReportFlowDoc"] as FlowDocument;
doc.DataContext = this.fdswReport.Document.DataContext; //your FlowDocumentScrollViewer
doc.PageWidth = prntDlg.PrintableAreaWidth;
doc.PageHeight = prntDlg.PrintableAreaHeight;
doc.ColumnWidth = prntDlg.PrintableAreaWidth;
doc.PagePadding = new Thickness(80);
doc.IsOptimalParagraphEnabled = true;
doc.IsHyphenationEnabled = true;
if (prntDlg.ShowDialog() == true)
prntDlg.PrintDocument(((IDocumentPaginatorSource)doc).DocumentPaginator, "Report");

Resources