I am trying to print a WPF FlowDocument to a particular printer, without prompting the user. The printer is a PDF converter.
This works great except that it prints to the default printer:
PrintDialog pd = new PrintDialog();
var doc = ((IDocumentPaginatorSource) RTB.Document).DocumentPaginator;
// I would like to explicitly set the printer to print to here.
pd.PrintDocument(doc, "Print Document");
In WinForms there is a System.Drawing.Printing.PrinterSettings object on document which has a PrinterName property which can be set to the printer I want, but I don't see that in WPF.
You first need a reference in your project to System.Printing. Then you can use the following code right after you declare your PrintDialog object.
pd.PrintQueue = new PrintQueue(new PrintServer(), "The exact name of my printer");
The PrintQueue is an object that represents the printer and everything else about that print queue.
This worked for me, when I used a shared network printer:
xPrintDialog.PrintQueue = New PrintQueue(New PrintServer("\\computer name"), "printer name")
Related
I am running the following code in a background thread as an STA apartment to provide a Print Preview in a document viewer:
// Print Preview
public static void PrintPreview(FixedDocument fixeddocument)
{
MemoryStream ms = new MemoryStream();
using (Package p = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite))
{
Uri u = new Uri("pack://TemporaryPackageUri.xps");
PackageStore.AddPackage(u, p);
XpsDocument doc = new XpsDocument(p, CompressionOption.Maximum, u.AbsoluteUri);
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
writer.Write(fixeddocument.DocumentPaginator);
var previewWindow = new Window();
var docViewer = new DocumentViewer();
previewWindow.Content = docViewer;
THIS FAILS ---> docViewer.CommandBindings.Remove(???Print Button???);
FixedDocumentSequence fixedDocumentSequence = doc.GetFixedDocumentSequence();
docViewer.Document = fixedDocumentSequence as IDocumentPaginatorSource;
previewWindow.ShowDialog();
PackageStore.RemovePackage(u);
doc.Close();
}
}
All works well. However, since this is running in its own thread--not the main thread--the print dialogue on the Document Viewer crashes.
In code, how can I remove and/or disable the Print button from the DocumentViewer?? (I have read everything I could find in Google, and it all is in XAML, not very helpful).
Any help is much appreciated. TIA
Update#1: The only way I can see to do this, is to drop the Print Button from the control template and use a custom Document Viewer. A workable style is given at Document Viewer Style.
It still would be nice if I could simply remove the button from the system Document viewer?
Using the method from this answer, you can alter the visibility of the PrintButton programmatically like this. Let's say I put the method in a class called UIElementHelper:
var button = UIElementHelper.FindChild<Button>(docViewer, "PrintButton");
button.Visibility = Visibility.Collapsed;
I am using DevXpress 14.
I want to use only one form name "FrmViewer" which contain DocumentVier to load any report I want.
This is the code, the datasource is not null (debugged), but the message is "The document contain no page". I think I missed some method of the documentViewer to start print
public FrmViewer(PhieuNhap pn)
{
InitializeComponent();
RptPhieuNhap rpt = new RptPhieuNhap();
rpt.DataSource = pn.ChiTietPhieuNhap;
rpt.nhacungcap.Value = pn.NhaCungCap.TenCC;
rpt.sophieu.Value = pn.SoPhieu;
documentViewer1.PrintingSystem = rpt.PrintingSystem;
}
You most likely need to call rpt.CreateDocument();
See here for more details:
https://www.devexpress.com/Support/Center/Question/Details/Q528191
I keep getting an "object reference not set to an instance of an object" and i have absolutely no idea why!
MediaElement1.Source = New URI(trackstream(0), UriKind.Absolute)
If i mouseover to check everything it seems fine, that variable position contains a direct link to an mp3, It even says if i mouseover it that the Source has been set to that URL but then i get this error.
i am just trying to set url as the first in a list that i have downloaded from a textfile previously, then put into that array. I have tried changing the urlkind and omitting it.
This works:
public MainWindow()
{
string[] trackstream = new string[] { #"C:\Users\Public\Music\Sample Music\sound.wma" };
InitializeComponent();
media.Source = new Uri(trackstream[0], UriKind.Absolute);
}
The more I read about the subject the less I understand so apologies in advance if the below seems completely off the wall.
I have a usercontrol that contains a flowdocument - a view with a corresponding viewmodel. The aim is to send this to a preview window where the user can view the document and also print it.
I lifted some code from an example at http://www.eggheadcafe.com/tutorials/aspnet/9cbb4841-8677-49e9-a3a8-46031e699b2e/wpf-printing-and-print-pr.aspx
When the below is called
Public Shared Sub PrintPreview(owner As Window, data As FormData)
Using xpsStream As New MemoryStream()
Using package__1 As Package = Package.Open(xpsStream, FileMode.Create, FileAccess.ReadWrite)
Dim packageUriString As String = "memorystream://data.xps"
Dim packageUri As New Uri(packageUriString)
PackageStore.AddPackage(packageUri, package__1)
Dim xpsDocument__2 As New XpsDocument(package__1, CompressionOption.Maximum, packageUriString)
Dim writer As XpsDocumentWriter = XpsDocument.CreateXpsDocumentWriter(xpsDocument__2)
Dim visual As New Form(data)
Dim printTicket As New PrintTicket()
printTicket.PageMediaSize = A4PaperSize
writer.Write(visual, printTicket)
Dim document As FixedDocumentSequence = xpsDocument__2.GetFixedDocumentSequence()
xpsDocument__2.Close()
Dim printPreviewWnd As New PrintPreviewWindow(document)
printPreviewWnd.Owner = owner
printPreviewWnd.ShowDialog()
PackageStore.RemovePackage(packageUri)
End Using
End Using
This brings up the print preview window and shows the user control that holds the flowdocument. However, it only shows the first of what should be multiple pages. I was under the assumption the whole point of writing the xps and then reading it back again in this window was to work around the problem of printing a visual but I'm obviously misunderstanding the whole process. Any help in getting through my thick head what I need to do to be able to view all of the pages in the document would be much appreciated.
Cheers
I thought the above with using xpsdocument and getfixeddocumentsequence would convert the flowdocument to a fixeddocument but seeing it doesn't, am I perhaps writing it wrongly??
You can print a visual to an XPS. However, as I understand it, it is your job to manage pages. If your visual is too big to fit on a page, you need to find a way to split it onto multiple pages.
The source code I posted here prints a list of items over many pages:
https://bitbucket.org/paulstovell/samples/src/a323f0c65ea4/XPS%20Report%20Generator/
If you can find a way to split your visuals (perhaps create 3 forms, with 15 items per form) into pages, you can then use this:
using (var doc = new XpsDocument("P:\\Test2.xps", FileAccess.Write))
{
var writer = XpsDocument.CreateXpsDocumentWriter(doc);
var collator = writer.CreateVisualsCollator();
collator.BeginBatchWrite();
collator.Write(form1);
collator.Write(form2);
collator.Write(form3);
collator.EndBatchWrite();
}
var doc2 = new XpsDocument("P:\\Test2.xps", FileAccess.Read);
var seq = doc2.GetFixedDocumentSequence();
var window = new Window();
window.Content = new DocumentViewer {Document = seq};
window.ShowDialog();
Also, note that if you're newing up a visual and printing it, you'll need to size it first, otherwise you may get an empty screen. Here's an example of generating a page of data (of course you'd change the sizes to fit an A4 sheet).
private StackPanel CreatePage()
{
var panel = new StackPanel();
panel.Width = 1000;
panel.Height = 1000;
for (var i = 0; i < 10; i++)
{
panel.Children.Add(new TextBlock() {Text = "Item " + i});
}
panel.Measure(new Size(1000, 1000));
panel.Arrange(new Rect(0, 0, 1000, 1000));
return panel;
}
What I am trying to do is so simple but I am having a hard time making it work. I saw some posts along the same lines but I still have questions.
I have a MenuItem object called mnuA. All I want is set the icon property programatically in C#. I have tried the following
a) mnuA.Icon = new BitmapImage{UriSource = new Uri(#"c:\icons\A.png")};
Results: Instead of showing the actual icon, I get the class name (System.Windows.Media.Imaging.BitmapImage)
b) mnuA.Icon = new BitmapImage(new Uri(#"c:\icons\A.png"));
Results: Instead of showing the actual icon, I get the path of the image (file:///c:/icons/A.png)
What am I doing wrong? Do I really need a converter class for something simple like this?
Try this:
Image img = new Image();
img.Source = new BitmapImage(new Uri(#"c:\icons\A.png"));
mnuA.Icon = img;
Might be a long shot, but try something like:
Uri u = new Uri(...); mnuA.Icon = new
BitmapImage(u);
What it seems its happening is that your icon is getting converted to a string.