Here's the whole workflow, start to finish. Each piece is broken down and explained below.
using GenerallyPositive;
using GenerallyPositive
using static GenerallyPositive
using static GenerallyPositive
using System
using Keys = System
static GPALButton startButton = GPAL
static GPALRadioButton chromeRadio = GPAL
static GPALRadioButton edgeRadio = GPAL
static GPALCheckbox overwriteCheckbox = GPAL
static GPALLabel titleLabel = GPAL
// approval popup shown after each row is filled in
static GPALLabel approvalLabel = GPAL
static GPALInput approvalReason = GPAL
static GPALButton approveButton = GPAL
static GPALButton notApproveButton = GPAL
static bool approvalResult = false;
static GPALForm approvalForm = GPAL
static GPALFile inputFile = ((GPALFile)@"c:sdiebay
[STAThread]
static void Main(string[] args)
{
GPALForm myForm = GPAL
myForm
}
public static CallIfStatus CallAfterFillIn(GPALForm myForm, IGPALGrid<string> tokens, int tokenIdx)
{
((TextBox)approvalReason
approvalForm
return CallIfStatus
}
private static void ApproveButtonClickHandler(object sender, EventArgs e)
{
approvalResult = true;
CloseParentForm(sender);
}
private static void NotApproveButtonClickHandler(object sender, EventArgs e)
{
approvalResult = false;
CloseParentForm(sender);
}
private static void CloseParentForm(object sender)
{
Control control = (Control)sender;
while (null != control
control = control
control
}
private static void StartButtonClickHandler(object sender, EventArgs e)
{
// kick off the automation workflow using the values chosen on the form
}
Every control follows the same shape: start from GPAL.Button, GPAL.RadioButton, GPAL.Checkbox, GPAL.Label, and so on, chain With* calls to configure it, then finish with ToGPALObject(). WithCallback wires up an event handler, WithShortcutKey adds an Alt-key accelerator, and WithChecked/WithText set initial state. The same pattern applies whether you're building a button, a combo box, a chart, or a tree view.
static GPALButton startButton = GPAL
static GPALRadioButton chromeRadio = GPAL
static GPALCheckbox overwriteCheckbox = GPAL
Because every control is a real object (gPalButton1, gPalRadioButton1, etc), you can read and write its state (Enabled, Checked, Text) from anywhere in the program - including from event handlers on other controls - using simple write-through property setters.
GPAL.Form is itself a fluent builder. WithFormControl adds each control in the order you want it laid out, and ToGPALObject() produces the GPALForm you'll show. CallAfterFillIn registers a callback that fires once per row when the form is later driven from a data file.
GPALForm myForm = GPAL
Show() makes the form visible but non-blocking, which gives FillInFrom something to update on screen as it works. FillInFrom(inputFile) walks the GPALFile row by row, populating matching controls from each row's values and firing CallAfterFillIn after each row. ShowDialog() then blocks until the user closes the form, the same way a normal modal dialog would.
myForm
Show() before ShowDialog() is only useful when something between them - like FillInFrom here - needs the form visible but non-blocking first. If you don't need that, just call ShowDialog() directly.
CallAfterFillIn receives the form, the full grid of tokens from the data file, and the index of the row just filled in. Here it pops up a small modal approval form next to the main form, positioned using the main form's Left/Top/Width so it doesn't overlap. Returning CallIfStatus.NotHandled lets GPAL continue its normal fill-in processing for the next row.
public static CallIfStatus CallAfterFillIn(GPALForm myForm, IGPALGrid<string> tokens, int tokenIdx)
{
((TextBox)approvalReason
approvalForm
return CallIfStatus
}
Calling ShowDialog() from inside CallAfterFillIn pauses the fill-in loop on that row until the approval form is closed. That's the point here - it forces a human decision per row - but be aware it turns an otherwise automatic loop into a step-through workflow.
Showing off some plain text in these paragraphs eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Here you can find different accents and emphasis sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
This is a link and how it could look like bestlinkinthebeautifulworld. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Here's just some classic bold text adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam notBoldSecondbestlinkinthebeautifulworld illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at adipisicing elit libero vel voluptas? Expedita, adipisicing facere dolores voluptatem ad ab rem assumenda soluta!
Other cuple of colors in case we want to emphasize several ways adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at voluptatem libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repudiandae quas consequuntur illo numquam assumenda autem exercitationem distinctio perspiciatis in natus. Eius dicta similique ipsam ipsa minima, nemo quae enim tempore.
GPAL
.CallIfNotFound(GenericCallIfNotFound)
.WithPublishToConsole();
//System.Drawing.Rectangle windowSize = new System.Drawing.Rectangle(10, 10, 1500, 1024);
// NOTE: we have to set browser = before we execute any steps
// this is due to the 'GenericCallIfNotFound' which might throw an exception, and BankScraper will not have the browser set when it calls scraper.Close()
// until the complete fluent line gets executed (meaning every step, meaning browser is not set until everything else succeeds)
browser = GPAL.Browser
.WithBrowserType(Enums.BrowserType.Chrome)
.WithProfileDataDirectory(ChromeProfileLocation)
.WithUseAutomationEngine(AutomationEngine.Selenium)
.WithWindowSize(new System.Drawing.Rectangle(0,0,1920,1080))
.ToGPALObject();