在我的C#应用程序中,我正在尝试生成打印预览而屏幕上没有显示进度对话框。
我相信你可以使用PrintDocument.PrintController来打印真实的(即不是打印预览版),但是在执行打印预览时它似乎不起作用。
我的代码如下:
public FrmDeliveryNotePrintPreview(DeliveryNote deliveryNote)
{
InitializeComponent();
this.Text = "Delivery Note #" + deliveryNote.Id.ToString();
// The print preview window should occupy about 90% of the
// total screen height
int height = (int) (Screen.PrimaryScreen.Bounds.Height * 0.9);
// Making an assumption that we are printing to A4 landscape,
// then adjust the width to give the correct height:width ratio
// for A4 landscape.
int width = (int) (height / 1.415);
// Set the bounds of this form. The PrintPreviewControl is
// docked, so it should just do the right thing
this.SetBounds(0, 0, width, height);
PrinterSettings printerSettings = new PrinterSettings();
PrintDeliveryNotes pdn = new PrintDeliveryNotes(
new DeliveryNote[] { deliveryNote },
printerSettings);
PrintDocument printDocument = pdn.PrintDocument;
printDocument.PrintController = new PreviewPrintController();
ppcDeliveryNote.Document = printDocument;
}
除了显示打印预览进度对话框之外,打印预览完全按照我的要求工作。
建议吗?
答案 0 :(得分:6)
这对我有用:
将文档的printcontroller设置为StandardPrintController
。
static class Program
{
static void Main()
{
PrintDocument doc = new PrintDocument();
doc.PrintController = new StandardPrintController();
doc.PrintPage += new PrintPageEventHandler(doc_PrintPage);
doc.Print();
}
static void doc_PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.DrawString("xxx", Control.DefaultFont, Brushes.Black, new PointF(e.PageBounds.Width / 2, e.PageBounds.Height / 2));
}
}
答案 1 :(得分:3)
只是为了确认Pooven的答案。我有同样的问题并试图解决,Stefan的解决方案也没有对我有用。然后我终于查看了源代码并发现它是硬编码的,因此无法更改。如果需要隐藏状态对话框,请寻找除PrintPreviewControl之外的其他解决方案。这是PrintPreviewControl的源代码。
private void ComputePreview() {
int oldStart = StartPage;
if (document == null)
pageInfo = new PreviewPageInfo[0];
else {
IntSecurity.SafePrinting.Demand();
PrintController oldController = document.PrintController;
// --> HERE they have hardcoded it! Why they do this!
PreviewPrintController previewController = new PreviewPrintController();
previewController.UseAntiAlias = UseAntiAlias;
document.PrintController = new PrintControllerWithStatusDialog(previewController,
SR.GetString(SR.PrintControllerWithStatusDialog_DialogTitlePreview));
// Want to make sure we've reverted any security asserts before we call Print -- that calls into user code
document.Print();
pageInfo = previewController.GetPreviewPageInfo();
Debug.Assert(pageInfo != null, "ReviewPrintController did not give us preview info");
// --> and then swap the old one
document.PrintController = oldController;
}
if (oldStart != StartPage) {
OnStartPageChanged(EventArgs.Empty);
}
}
答案 2 :(得分:2)
我不想回答我自己的问题,但是解决方案正在盯着我。
由于我已经编码了打印交货单的能力,我的下一步是提供屏幕上的复印件(即无意打印硬拷贝)。打印预览对话框似乎很简单。
最后,我刚创建了一个自定义表单并直接在其上绘制,没有打印预览控件。
不幸的是,我过于专注于尝试让打印预览对话按照我的意愿行事,而不是考虑更大的问题。
答案 3 :(得分:2)
我想我做到了。使用此类而不是PrintPreviewControl:
public class PrintPreviewControlSilent : PrintPreviewControl
{
public new PrintDocument Document
{
get { return base.Document; }
set
{
base.Document = value;
PreviewPrintController ppc = new PreviewPrintController();
Document.PrintController = ppc;
Document.Print();
FieldInfo fi = typeof(PrintPreviewControl).GetField("pageInfo", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
fi.SetValue(this, ppc.GetPreviewPageInfo());
}
}
}
答案 4 :(得分:1)
您可能会对PreviewPrintController而不是StandardPrintController感到幸运。
答案 5 :(得分:0)
解决方法是使用EnumChildWindows API查找窗口的句柄,如果找到,请使用ShowWindow API和SW_HIDE标志来隐藏窗口。
如果你知道窗口的标题,这是一个使用FindWindow的例子:
#region Constants
private const int SW_HIDE = 0;
private const int SW_SHOWNORMAL = 1;
private const int SW_SHOW = 5;
#endregion Constants
#region APIs
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
private static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
private static extern bool EnableWindow(IntPtr hwnd, bool enabled);
#endregion APIs
public static void ShowProgress()
{
IntPtr h = FindWindow(null, "titleofprogresswindow");
ShowWindow(h, SW_SHOW);
EnableWindow(h, true);
}
public static void HideProgress()
{
IntPtr h = FindWindow(null, "titleofprogresswindow");
ShowWindow(h, SW_HIDE);
EnableWindow(h, false);
}
答案 6 :(得分:0)
似乎PrintPreviewControl
使用的PrintPreviewDialog
将替换PrintController
的{{1}},以便在预览呈现过程中使用PrintDocument
。完成PrintControllerWithStatusDialog
操作后,Print
将恢复为之前的值。似乎无法自定义PrintController
以使用任何其他PrintPreviewControl
。
答案 7 :(得分:0)
一个对我有用的解决方案是使用Harmony(v1.2)并修补上述ComputePreview
的{{1}}函数:
补丁类如下
PrintPreviewControl
要应用补丁,您需要在应用程序启动时包括以下两行:
[Harmony.HarmonyPatch(typeof(System.Windows.Forms.PrintPreviewControl))]
[Harmony.HarmonyPatch("ComputePreview")]
class PrintPreviewControlPatch
{
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
var cis = new List<CodeInstruction>(instructions);
// the codes 26 to 28 deal with creating the
// progress reporting preview generator that
// we don't want. We replace them with No-Operation
// code instructions.
cis[26] = new CodeInstruction(OpCodes.Nop);
cis[27] = new CodeInstruction(OpCodes.Nop);
cis[28] = new CodeInstruction(OpCodes.Nop);
return cis;
}
}