I believe I know the cause of this issue but I'm unsure how to fix it.
I am using WinForms with the MVP(model-view-presenter) approach.
I have an event which has a subscriber, this subscriber calls a method which opens a new instance of a form and draws rectangles on the form. The form should look like this:
Now to get this to work on any page, I plan on resizing the rectangle based on the size of the form. I receive the data from the user on a form previously filled out.
My subscriber looks like this:
private void ValidateFormBeforeDiagram(object sedner, OptionOneCheckedEventArgs e) {
try {
//Create variables
int pagesUp = e.IsOptionOneChecked ? view.OptionOneAround : view.OptionTwoAround;
int pagesAcross = e.IsOptionOneChecked ? view.OptionOneAcross : view.OptionTwoAcross;
float pageWidth = e.IsOptionOneChecked ? view.PageSizeLength : view.PageSizeWidth;
float pageLength = e.IsOptionOneChecked ? view.PageSizeWidth : view.PageSizeLength;
ParametersToCreatePrintingDiagram parameters = new ParametersToCreatePrintingDiagram(view.SheetSizeAcross, view.SheetSizeAround,
pagesUp, pagesAcross, pageWidth, pageLength);
//Check if form is open, if so close it
if (Application.OpenForms.OfType<PrintingDesignForm>().Any()) {
Application.OpenForms.OfType<PrintingDesignForm>().First().Close();
}
//Create a new instance of the form
PrintingDesignForm form = new PrintingDesignForm();
float ratio = 0;
//If rectangle is larger than the client viewable size then scale the rectangle so it will fit.
if (parameters.RectangleHeight > form.ClientRectangle.Height || parameters.RectangleWidth > form.ClientRectangle.Height) {
var ratioX = form.ClientRectangle.Height / parameters.RectangleHeight;
var ratioY = form.ClientRectangle.Width / parameters.RectangleWidth;
ratio = Math.Min(ratioX, ratioY);
parameters.RectangleHeight = parameters.RectangleHeight * ratio - parameters.RectangleXPosition;
parameters.RectangleWidth = parameters.RectangleWidth * ratio - parameters.RectangleYPosition;
}
//Draw the main rectangle
form.Paint += (se, pe) => {
var r = new Rectangle(parameters.RectangleXPosition, parameters.RectangleYPosition,
(int)Math.Round(parameters.RectangleWidth), (int)Math.Round(parameters.RectangleHeight));
var brush = new SolidBrush(Color.FromArgb(255, 255, 204));
pe.Graphics.FillRectangle(brush, r);
using (var pen = new Pen(brush.Color, 2))
pe.Graphics.DrawRectangle(pen, r);
};
int leftXInches;
int topYInches;
int xInch = 0;
int yInch = 0;
List<Rectangle> rectArr = new List<Rectangle>();
//Calculate the smaller rectangle sizes and positions
for (int i = 1; i < parameters.PagesUp; i++) {
for (int j = 1; j < parameters.PagesAcross; j++) {
if (e.IsOptionOneChecked) {
leftXInches = (int)Math.Round(parameters.RectangleXPosition
+ ((view.SheetSizeAcross - (view.PageSizeLength * view.OptionOneAcross) - (view.OptionOneAcross - 1) * view.Bleeds) / 2)
+ ((j - 1) * parameters.PageWidth)
+ ((j - 1) * view.Bleeds));
topYInches = (int)Math.Round(parameters.RectangleYPosition
+ ((view.SheetSizeAround - (view.PageSizeLength * view.OptionOneAround) - (view.OptionOneAround - 1) * view.Bleeds) / 2)
+ ((i - 1) * parameters.PageHeight)
+ ((i - 1) * view.Bleeds));
}
else {
leftXInches = (int)Math.Round(parameters.RectangleXPosition
+ ((view.SheetSizeAcross - (view.PageSizeWidth * view.OptionTwoAcross) - (view.OptionTwoAcross - 1) * view.Bleeds) / 2)
+ ((j - 1) * parameters.PageWidth)
+ ((j - 1) * view.Bleeds));
topYInches = (int)Math.Round(parameters.RectangleYPosition
+ ((view.SheetSizeAround - (view.PageSizeLength * view.OptionTwoAround) - (view.OptionTwoAround - 1) * view.Bleeds) / 2)
+ ((i - 1) * parameters.PageHeight)
+ ((i - 1) * view.Bleeds));
}
var width = (int)((Math.Round(parameters.PageWidth) * 72) * ratio);
var height = (int)((Math.Round(parameters.PageHeight) * 72) * ratio);
yInch = (int)Math.Round((topYInches * 72) * ratio);
//Increase the xInch every loop as you need to make sure that there is room for other rectangles
if (j == 1) {
xInch = (int)Math.Round((leftXInches * 72) * ratio);
}
else {
xInch += width + 20;
}
//Add rectangle with specs ready to be painted onto the form
rectArr.Add(new Rectangle(xInch, yInch, width, height));
}
}
//Paint the smaller rectangles onto the form
for (int i = 0; i < rectArr.Count; i++) {
form.Paint += (se, pe) => {
var r = rectArr[i]; //Exception occurs on this line
var brush = new SolidBrush(Color.FromArgb(255, 0, 0));
pe.Graphics.FillRectangle(brush, r);
using (var pen = new Pen(brush.Color, 2))
pe.Graphics.DrawRectangle(pen, r);
};
}
form.Show();
}
catch (Exception ex) {
LogErrorToView(this, new ErrorEventArgs(ex.Message));
}
}
I have commented above where the exception occurs. It happens because after this class has run its course, the publisher event is completed. After this happens the two other paint events get called and it errors because rectArr
is no longer in scope.
Is there any way I can fix this?
EDIT: Why the downvote?