I have got something like that to work ... mine takes all the objects from a particular stackpanel and scales them to a page and then puts them back
Print Class :
public class PrintReport
{
private Grid _visual;
private StackPanel _panel;
private FrameworkElement _header;
private string _pageText = "Page ";
private string _dateText = "Date ";
private string _title;
private string _subTitle;
public StackPanel pageroot;
public PrintReport()
{
_visual = new Grid();
_panel = new StackPanel()
{
Margin = new Thickness(40),
};
PageNumber = 0;
_visual.Children.Add(_panel);
}
public void Print()
{
CreateHeader();
var pd = new PrintDocument();
pd.DocumentName = this.Title;
pd.PrintPage += new EventHandler<PrintPageEventArgs>(pd_PrintPage);
pd.EndPrint += new EventHandler<EndPrintEventArgs>(pd_EndPrint);
pd.Print();
}
void pd_EndPrint(object sender, EndPrintEventArgs e)
{
OnEndPrint(e);
}
private UIElement currentElement = null;
private List<UIElement> pastElements = new List<UIElement>();
private void pd_PrintPage(object sender, PrintPageEventArgs e)
{
PageNumber++;
if (currentElement != null)
{
_panel.Children.Remove(currentElement);
pastElements.Add(currentElement);
}
currentElement = pageroot.Children.First();
if (_panel.Children.Count == 0)
{
_panel.Children.Add(_header);
}
_visual.Height = e.PrintableArea.Height;
_visual.Width = e.PrintableArea.Width;
double totalHeight = e.PrintableArea.Height - this.Margin.Top - this.Margin.Bottom;
double totalWidth = e.PrintableArea.Width - this.Margin.Left - this.Margin.Right;
double height;
if (_header.ActualHeight > 0)
{
height = _header.ActualHeight;
}
else
{
_header.Measure(new Size(totalWidth, totalHeight));
height = _header.DesiredSize.Height;
}
var hold = currentElement;
pageroot.Children.Remove(hold);
_panel.Children.Add(hold);
e.PageVisual = _visual;
e.HasMorePages = pageroot.Children.Count > 0;
}
private TransferCalcs CalcScaleVar(double objW, double objH, double totalWidth, double printHeight, double TopMargin, double BotMargin, double Header)
{
var retVal = new TransferCalcs();
retVal.scaleX = totalWidth / objW;
retVal.TranslateX = (objW - totalWidth) / 2;
retVal.scaleY = (printHeight - TopMargin - BotMargin - Header) / objH;
return retVal;
}
private void CreateHeader()
{
var border = new Border()
{
BorderThickness = new Thickness(2),
BorderBrush = new SolidColorBrush(Colors.Black),
Margin = new Thickness(0, 0, 0, 10),
CornerRadius = new CornerRadius(3),
};
var grid = new Grid();
grid.ColumnDefinitions.Add(new ColumnDefinition()
{
Width = new GridLength(10)
});
grid.ColumnDefinitions.Add(new ColumnDefinition()
{
Width = new GridLength(1, GridUnitType.Star)
});
grid.ColumnDefinitions.Add(new ColumnDefinition()
{
Width = new GridLength(0, GridUnitType.Auto)
});
grid.ColumnDefinitions.Add(new ColumnDefinition()
{
Width = new GridLength(0, GridUnitType.Auto)
});
grid.ColumnDefinitions.Add(new ColumnDefinition()
{
Width = new GridLength(10)
});
grid.RowDefinitions.Add(new RowDefinition()
{
Height = new GridLength(0, GridUnitType.Auto)
});
grid.RowDefinitions.Add(new RowDefinition()
{
Height = new GridLength(0, GridUnitType.Auto)
});
// Title
var tb = new TextBlock()
{
FontWeight = FontWeights.Bold,
FontSize = 14,
};
tb.SetBinding(TextBlock.TextProperty, new Binding()
{
Path = new PropertyPath("Title"),
Source = this,
});
grid.Children.Add(tb);
Grid.SetColumn(tb, 1);
// SubTitle
tb = new TextBlock();
tb.SetBinding(TextBlock.TextProperty, new Binding()
{
Path = new PropertyPath("SubTitle"),
Source = this,
});
grid.Children.Add(tb);
Grid.SetColumn(tb, 1);
Grid.SetRow(tb, 1);
// PageText
tb = new TextBlock()
{
VerticalAlignment = VerticalAlignment.Center,
};
tb.SetBinding(TextBlock.TextProperty, new Binding()
{
Path = new PropertyPath("PageText"),
Source = this,
});
grid.Children.Add(tb);
Grid.SetColumn(tb, 2);
// DateText
tb = new TextBlock();
tb.SetBinding(TextBlock.TextProperty, new Binding()
{
Path = new PropertyPath("DateText"),
Source = this,
});
grid.Children.Add(tb);
Grid.SetColumn(tb, 2);
Grid.SetRow(tb, 1);
// PageNumber
tb = new TextBlock()
{
VerticalAlignment = VerticalAlignment.Center,
};
tb.SetBinding(TextBlock.TextProperty, new Binding()
{
Path = new PropertyPath("PageNumber"),
Source = this,
});
grid.Children.Add(tb);
Grid.SetColumn(tb, 3);
// DateValue
tb = new TextBlock()
{
Text = DateTime.Today.ToShortDateString(),
};
grid.Children.Add(tb);
Grid.SetColumn(tb, 3);
Grid.SetRow(tb, 1);
border.Child = grid;
Header = border;
}
public event EventHandler<EndPrintEventArgs> EndPrint;
protected virtual void OnEndPrint(EndPrintEventArgs e)
{
if (currentElement != null)
{
_panel.Children.Remove(currentElement);
pastElements.Add(currentElement);
}
foreach (var item in pastElements)
{
pageroot.Children.Add(item);
}
var handler = EndPrint;
if (handler != null)
{
handler(this, e);
}
}
public int _pageNumber { get; set; }
#region PropertyFields
public FrameworkElement Header
{
get { return _header; }
set { _header = value; }
}
public Thickness Margin
{
get { return _panel.Margin; }
set { _panel.Margin = value; }
}
public string Title
{
get { return _title; }
set
{
if (_title != value)
{
_title = value;
OnPropertyChanged("Title");
}
}
}
public string SubTitle
{
get { return _subTitle; }
set
{
if (_subTitle != value)
{
_subTitle = value;
OnPropertyChanged("SubTitle");
}
}
}
public string PageText
{
get { return _pageText; }
set
{
if (_pageText != value)
{
_pageText = value;
OnPropertyChanged("PageText");
}
}
}
public string DateText
{
get { return _dateText; }
set
{
if (_dateText != value)
{
_dateText = value;
OnPropertyChanged("DateText");
}
}
}
public int PageNumber
{
get { return _pageNumber; }
set
{
if (_pageNumber != value)
{
_pageNumber = value;
OnPropertyChanged("PageNumber");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
Usage :
private PrintReport printReport;
private void PrintButton_Click(object sender, RoutedEventArgs e)
{
printReport = new PrintReport()
{
SubTitle = init.PrettyFieldName,
Title = "Entire Screen Sample" + (DateTime.Now - new DateTime(2009, 12, 23)).TotalMilliseconds,
}
printReport.pageroot = pageroot;
printReport.Print();
}