Invalid printer exception - c#

I have following code in a printing dialog in a windows form.
myPrintDialog = new PrintDialog();
System.Drawing.Bitmap memoryImage = new System.Drawing.Bitmap(pnVTCard.Width, pnVTCard.Height);
pnVTCard.DrawToBitmap(memoryImage, pnVTCard.ClientRectangle);
if (myPrintDialog.ShowDialog() == DialogResult.OK)
{
System.Drawing.Printing.PrinterSettings values;
values = myPrintDialog.PrinterSettings;
myPrintDialog.Document = printDocument1;
printDocument1.PrintController = new StandardPrintController();
printDocument1.Print();//This line shows system.drawing invalid printer exception when i hover over the code.
saveToVC(Convert.ToInt32(cmbVID.SelectedItem.ToString()), cmbElectionName.SelectedItem.ToString());
}
printDocument1.Dispose();
public System.Drawing.Printing.PrintDocument printDocument1 { get; set; }
when I try to handle the exception it shows null reference. Can someone kindly show what to correct.
As I don't know much about this can some one explain me what the wrong I'm doing here.?
pnVTcard is a panel control

Make sure you use references which are set to an instance of an object (sounds familiar? :) )
Maybe you are not setting printDocument1 before accessing its properties. Or maybe some other object, like those cmb... SelectedItem.
If you still can't pinpoint the culprit, go ahead and use break points and manually inspect the references.

Related

Outlook AddIn Zoom.Percentage

Im trying to translate this VBA code from an Outlook AddIn to C#
Private Sub objInspector_Activate() Handles objInspector.Activate
Dim wdDoc As Microsoft.Office.Interop.Word.Document = objInspector.WordEditor
wdDoc.Windows(1).Panes(1).View.Zoom.Percentage = lngZoom
End Sub
But I can't get access to the Panes.View.Zoom.Percentage property
The main idea is that when the user opens an email, he will get a custom zoom level.
What I got at the moment is:
void Inspector_Activate()
{
// this bool is true
// bool iswordMail = objInspector.IsWordMail();
//I get the word document
Document word = objInspector.WordEditor as Microsoft.Office.Interop.Word.Document;
word.Application.ActiveDocument.ActiveWindow.View.Zoom.Percentage = 150;
// at this point i'm getting an exception
// I've also tried with
// word.ActiveWindow.ActivePane.View.Zoom.Percentage = 150; getting the same exception
}
The exception is :
An exception of type 'System.Runtime.InteropServices.COMException'
occurred in OutlookAddInTest.dll but was not handled in user code
Additional information: This object model command is not available in
e-mail.
I'm quite new in C# and Office addins, any advise?
Use word.Windows.Item(1).View.Zoom.Percentage = 150 (where word comes from Inspector.WordEditor)
word.Application.ActiveDocument.ActiveWindow.View.Zoom.Percentage = 150;
What property exactly fires the exception?
Anyway, there is no need to call the Application and ActiveDocument properties in the code. The WordEditor property of the Inspector class returns an instance of the Document class (not Word Application instance).
Thanks to Eugene Astafiev for his help.
The square brackets did the trick
VBA
Private Sub objInspector_Activate() Handles objInspector.Activate
Dim wdDoc As Microsoft.Office.Interop.Word.Document = objInspector.WordEditor
wdDoc.Windows(1).Panes(1).View.Zoom.Percentage = 150
End Sub
C#
private void Inspector_Activate()
{
Document wdDoc = objInspector.WordEditor;
wdDoc.Windows[1].Panes[1].View.Zoom.Percentage = 150;
}
I've been wanting this forever, and then I stumbled on a nice project in the MSDN Gallery Outlook 2010: Developing an Inspector Wrapper. It has a set of wrappers for all the Outlook objects, so you get a true event for every item of interest. Not sure if it's the most efficient thing ever, but it seems to work.
I have trouble with my eyesight so want black everything, and zoom everything. I seem to be able to do that by overriding the Activate() method. It's all pretty new so we'll see if it survives long term.
protected virtual void Activate() {
var activeDocument = Inspector.WordEditor as Document;
if (activeDocument == null)
return;
var mailZoom = GetSetting("MailZoom", 125);
if (mailZoom != 0)
activeDocument.Windows[1].View.Zoom.Percentage = mailZoom;
if (GetSetting("MailBlack", true)) {
activeDocument.Background.Fill.ForeColor.RGB = 0;
activeDocument.Background.Fill.Visible = msoTrue;
activeDocument.Saved = true;
}
}
In this example, GetSetting is just a function that returns a setting from an INI file. you can use constants or some other storage method.
There might be a better way to get the white on black text, but this seems pretty good.

Highlighting a particular control while capturing screenshot of a dialog in web page in c#

I have a requirement to capture the screen shot of the opened dialog with a particular html control highlighted ( whose static id is given ). currently I Implemented the code following manner :
public void Snapshot()
{
Image currentImage = null;
currentImage = GetOpenedDialogFrame().CaptureImage();
}
public UITestControl GetOpenedDialogFrame()
{
var dialogsFrames = new HtmlDiv(this.BrowserMainWindow.UiMobiControlDocument);
dialogsFrames.SearchProperties.Add(new PropertyExpression(HtmlControl.PropertyNames.Class, "mcw-dialog", PropertyExpressionOperator.Contains));
var dialogs = dialogsFrames.FindMatchingControls();
if (dialogs.Count == 0)
{
return null;
}
return dialogs[dialogs.Count - 1];
}
Now I have to write the code to highlight the particular html control while taking a screenshot. The DrawHighlight() method of Microsoft.VisualStudio.TestTools.UITesting.dll does not take any parameter so how can I highlight a particular html control in the screenshot.
DrawHighlight() is a method of a UI Control. It could be used in this style:
public void Snapshot()
{
Image currentImage = null;
var control = GetOpenedDialogFrame();
// TODO: protect the code below against control==null.
control.DrawHighlight();
currentImage = control.CaptureImage();
}
Whilst that answers your question about DrawHighlight, I am not sure it will achieve what you want. Please see this question the Microsoft forums where they are trying to do a similar screen capture.
Why not simply user the playback settings:
Playback.PlaybackSettings.LoggerOverrideState = HtmlLoggerState.AllActionSnapshot;
This will produce the html log file with all the screenshots that your codedui test went threw.
After searching for the matching controls you can try to highlight each one of them.
something like:
foreach( var control in controls)
{
control.drawhighlight();
}
that way you'll be able to which controls are located by the playback(qtagent to be more precise). furthermore this will help you decide which instance to refer to. (run and wait to see which controls are highlighted, pick the one you need and hard code it to be part of the test).
so after the test run you'll end up with something like:
var dialogs = dialogsFrames.FindMatchingControls();
dialogs[desiredLocation].drawhighlight();
hope this helps.

Why "this" works but "Form.Activeform" throws NullRefernceException?

if this keyword refers to the current instance of the class as instanced in program class(Application.Run(new Form1()))
we can reach it's properties with this keyword
this .Text = "debuggging";
this .Opacity = 54;
this .ShowIcon = true;
this .Size = new Size(100, 100);
why cant ı reach it with Form1.ActiveForm.*(All properties)
just out of curiosity but why
when coded like this
Form1.ActiveForm.Text = "debugla";
Form1.ActiveForm.Opacity = 54;
Form1.ActiveForm.ShowIcon = true;
Form1.ActiveForm.Size = new Size(100, 100);
and activeform must bring us the currently active form used
it throws nullreference exception why ?
MSDN: Form.ActiveForm: "A Form that represents the currently active form, or null if there is no active form."
So maybe because you are debugging the form is not active(has not focus), therefore it returns null.
ActiveForm returns the active form... this means that if your window doesn't have focus, then it is not active. Therefore by using it in this way you greatly risk your program producing an error.
Using this ensures you are accessing the form you are intending to change
You should also note that ActiveForm is a static property and therefore it has no link whatsoever to the form you are using it in if you have any other windows open in your application then your changes could apply to these other dialogs
You can do this:
Form currentForm = Form.ActiveForm;
if(currentForm != null)
{
//use currentForm properties
}
Form.ActiveFormgets the currently active form for this application.
while this refers to current instance of Form1.

using an array of Settings in C#

i want to write a program that somehow is like a designer where user can add textbox on the form and everything the user put into those textbox can be saved (like a setting) and after closing and opening the form again textboxs' text will remail unchanged.
so i decided to make a setting in project->settings and then make an array of it in my code.
but whenever i want to access my settings it gives me an exception:
"An unhandled exception of type 'System.NullReferenceException' occurred in FormDesigner.exe"
here is my code from defining the array:
Settings[] formsetting=new Settings[3];
and here is my code for handling the textchanged event for everytext box:
(i use the textboxs' tag to match the settings index with every textbox)
void t_TextChanged(object sender, EventArgs e)
{
TextBox temp = (TextBox)sender;
int s =(int) temp.Tag;
string str = temp.Text;
frmsetting[s].text = str;
}
the last line is where i get the error.
could someone explain to me what is the problem and how to fix it?
and if my way is wrong could you please show my another way of doing this.
thanks
You haven't initialized the objects in the array.
Doing this:
Settings[] formsetting = new Settings[3];
..creates the array. All 3 are null though. Do this:
var formsetting = new Settings[3] {
new Settings(),
new Settings(),
new Settings()
};
While you are initializing your array, you are not actually initializing any of the values. What you have currently is equivalent to the following:
Settings[] formsetting=new Settings[3];
formsetting[0] = null;
formsetting[1] = null;
formsetting[2] = null;
You need to initialize the value at the index you want to use before doing anything with it.

Page-Range-Problem at Printing a Document

i try to print out the content of my editor:
PrintDialog pd = new PrintDialog();
pd.PageRangeSelection = PageRangeSelection.AllPages;
pd.UserPageRangeEnabled = true;
FlowDocument fd = DocumentPrinter.CreateFlowDocumentForEditor(CurrentDocument.Editor);
DocumentPaginator dp = ((IDocumentPaginatorSource)fd).DocumentPaginator;
bool? res = pd.ShowDialog();
if (res.HasValue && res.Value)
{
fd.PageHeight = pd.PrintableAreaHeight;
fd.PageWidth = pd.PrintableAreaWidth;
fd.PagePadding = new Thickness(50);
fd.ColumnGap = 0;
fd.ColumnWidth = pd.PrintableAreaWidth;
pd.PrintDocument(dp, CurrentDocument.Editor.FileName);
}
The test-document i used has about 14 pages (with this pagesize-settings).
i tested it: the printdialog appears and I´ve chosen a pagerange (i typed "1-3" into the textbox) and clicked print. above the printdocument() I set a breakpoint and looked into the printdialog-object. it says pd.PageRangeSelection = PageRangeSelection.UserPage and pd.PageRange = {1-3}. I guess this is right, because I wanted to print out only page 1-3. then the printdocument() executed and in the output-pdf (for testing I use a pdf-printer) has 14 pages (the whole document was printed).
where is my mistake? why does the pagerange-setting not work?
thanks for your help
In your code you manually set:
pd.PageRangeSelection = PageRangeSelection.AllPages;
This is why your code prints all the pages.
The reason for this is because FlowDocument's DocumentPaginator does not handle UserPageRanges. You can see that FlowDocument implementation creates a FlowDocumentPaginator, and it doesn't take into account ranges.
If it did handle it, in FlowDocumentPaginator.(Async)GetPage you would see, code checking to see if the page requested to be printed is in an index of available pages; or maybe if a key exists in a Dictionary whose value is the DocumentPage to print.
In other words, and the reason the PrintDialog default has UserPageRangeEnabled set to false, is because in order to use that feature, you'll usually have to write your own DocumentPaginator or you have to add some logic to compile a new temporary document to hold only the pages you want to print.
Feel free to ask any questions.

Categories