So I'm not actually sending arguments, but setting a class variable to a certain value, then using it again in another method. Is this the "best practice" way to do things? If not, I'd be interested in learning the correct way. Thanks! Can/Should the arguments be sent some other way?
private string PrintThis;
public void PrintIt(string input){
PrintThis = input; //SETTING PrintThis HERE
static private PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(PrintDocument_PrintSomething);
pd.Print();
}
private void PrintDocument_PrintSomething(Object sender, PrintPageEventArgs e) {
e.Graphics.DrawString(PrintThis, new Font("Courier New", 12), Brushes.Black, 0, 0);
//U开发者_Go百科SING PrintThis IN THE ABOVE LINE
}
Closures were introduced into the language to solve this very problem.
By capturing the appropriate variable, you can give it storage that 'outlives' the containing method:
// Note that the 'input' variable is captured by the lambda.
pd.PrintPage += (sender, e) => Print(e.Graphics, input);
...
static void Print(Graphics g, string input) { ... }
Do note that this very much a convenience feature; the way the compiler solves this problem on your behalf is suspiciously similar to your own, existing solution. (There are certain differences, e.g. the captured variable ends up as a field of a newly created object of some other (generated) class. Your existing solution does not do this: you have one 'temporary' storage location per instance of your class rather than per call to PrintIt
, which is not good - it isn't thread-safe, for example)
Not normally, but for this API (WinForms printing) it is the usual approach.
Consider that PrintThis is not just a variable but your "model" or "document".
Alternatively, you can use inheritance:
class MyPrintDocument : PrintDocument
{
public delegate void MyPrintPageEventHandler (object, PrintPageEventArgs, object); // added context!
public event MyPrintPageEventHandler MyPrintPageEvent;
public MyPrintDocument (object context) { m_context = context; }
protected void OnPrintPage (PrintPageEventArgs args)
{
// raise my version of PrintPageEventHandler with added m_context
MyPrintPageEvent (this, args, m_context);
}
object m_context;
}
public void PrintIt(string input)
{
MyPrintDocument pd = new MyPrintDocument(input);
pd.MyPrintPage += new MyPrintPageEventHandler (PrintDocument_PrintSomething);
pd.Print();
}
private void PrintDocument_PrintSomething(Object sender, PrintPageEventArgs e, object context)
{
e.Graphics.DrawString((string) context, new Font("Courier New", 12), Brushes.Black, 0, 0);
}
精彩评论