Friday, September 25, 2015

Creating a very simple Ajax Form in ASP.NET MVC 4

In this post, I am going to demonstrate how to create a simple Ajax Form in ASP.NET MVC 4 application using Visual Studio.  I am using Visual Studio 2015 but this should work with VS 2013 too. We are going to submit information about a person using some ajax and with minimum use of javascript.  There is javascript used but we are taking advantage of the wonderful tooling and template benefits of ASP.NET MVC4.  I assume you know some basics of ASP.NET MVC 4 but to get started you create a default asp.net mvc 4 application inside visual studio.

Before diving right into code you may want to check the pre-requisites section below.

PREREQUISITES

Packages.

 You will need if not already installed jQuery, jQuery.UI.Combined, jQuery.Validation, Microsoft.jQuery.Unobtrusive.Ajax, Microsoft.jQuery.Unobtrusive.Validation. Below is how my packages look like.

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Antlr" version="3.4.1.9004" targetFramework="net451" />
  <package id="bootstrap" version="3.0.0" targetFramework="net451" />
  <package id="EntityFramework" version="6.1.1" targetFramework="net451" />
  <package id="jQuery" version="1.10.2" targetFramework="net451" />
  <package id="jQuery.UI.Combined" version="1.11.2" targetFramework="net451" />
  <package id="jQuery.Validation" version="1.13.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.Identity.Core" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.Identity.EntityFramework" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.Identity.Owin" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.Mvc" version="5.2.2" targetFramework="net451" />
  <package id="Microsoft.AspNet.Razor" version="3.2.2" targetFramework="net451" />
  <package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net451" />
  <package id="Microsoft.AspNet.WebPages" version="3.2.2" targetFramework="net451" />
  <package id="Microsoft.jQuery.Unobtrusive.Ajax" version="3.2.2" targetFramework="net451" />
  <package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.2" targetFramework="net451" />
  <package id="Microsoft.Owin" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.Cookies" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.Facebook" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.Google" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.MicrosoftAccount" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.OAuth" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.Twitter" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net451" />
  <package id="Modernizr" version="2.6.2" targetFramework="net451" />
  <package id="Newtonsoft.Json" version="6.0.3" targetFramework="net451" />
  <package id="Owin" version="1.0" targetFramework="net451" />
  <package id="Respond" version="1.2.0" targetFramework="net451" />
  <package id="WebGrease" version="1.5.2" targetFramework="net451" />
</packages>

Bundles

 public class BundleConfig
{
// For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));

bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*",
"~/Scripts/jquery.unobtrusive-ajax*"));

bundles.Add(new ScriptBundle("~/bundles/jqueryui")
.Include("~/Scripts/jquery-ui-*"));

bundles.Add(new StyleBundle("~/Content/jquerycss")
.Include("~/Content/themes/base/datepicker.css"));

bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));

bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"));

bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css"));

// Set EnableOptimizations to false for debugging. For more information,
// visit http://go.microsoft.com/fwlink/?LinkId=301862
BundleTable.EnableOptimizations = true;
}
}

Let’s dive in.


First we create a person class i.e model in the models folder inside your application. Notice the data annotations used to trigger form validation. These will be triggered on the client side when the user enters invalid information. Most of them are self explanatory however special mention to the confirm password field. It is so easy to do password confirmation here.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace AspNetAjaxForm.Models
{
public class Person
{
[Required()]
[DataType(DataType.Text)]
[StringLength(50, MinimumLength = 3)]
public string FirstName { get; set; }

[Required()]
[DataType(DataType.Text)]
[StringLength(50, MinimumLength = 3)]
public string LastName { get; set; }

[Required]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }

[Required]
public DateTime BirthDate { get; set; }

[DataType(DataType.Text)]
[StringLength(50,MinimumLength=6)]
[Required]
public string Username { get; set; }

[DataType(DataType.Password)]
[StringLength(255, MinimumLength = 8)]
[Required]
public string Password { get; set; }

[Compare("Password")]
[DataType(DataType.Password)]
[StringLength(255, MinimumLength=8)]
public string ConfirmPassword { get; set; }
}
}

Next we will create Register.cshtml page as shown below inside Views/Home folder.  For explanation see paragraph below code

@model AspNetAjaxForm.Models.Person
@{
ViewBag.Title = "Register";
}
<h2>Register</h2>
<div id="register-main">
<div id="register-main-loading-img">
<img id="loading-img" alt="loading" src="~/Content/loadingAnimation.gif">
</div>
@Html.Partial("_RegisterForm",Model)
</div>
@section scripts
{
<script type="text/javascript">
$(document).on('focus', '[data-date="birthdate"]', function () {
$(this).datepicker({
changeMonth: true,
changeYear: true
});
});
</script>
}

In the code above we specify that this form will take in strongly typed model Person. In the register-main div we have two things, one is loading image which is a spinning .gif image that you can easily get from internet and the other is a Partial view called _RegisterForm.cshtml that accepts our Model object. We will create _RegisterForm in the next step.  In the Scripts section we use Jquery to configure our date picker to show month and year field to select Birthdate. Lets’ create _RegisterForm view using the create template with Person as strongly typed object.  Now I have modified the form to use Ajax.BeginForm.  See description of the code below.

@model AspNetAjaxForm.Models.Person

<div id="ajaxForm">
@using (Ajax.BeginForm("Register", "Home", null,
new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.ReplaceWith,
UpdateTargetId = "ajaxForm",
LoadingElementId = "register-main-loading-img"
}))
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
<h4>Person</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.BirthDate, htmlAttributes: new { @class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.BirthDate, new { htmlAttributes = new { @class = "form-control", data_date = "birthdate" } })
@Html.ValidationMessageFor(model => model.BirthDate, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Username, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Username, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>

In the above code, first line is obvious it takes in Person object. We wrap everything into ajaxForm div. The key parts here are as follows:


1. Using Ajax.BeginForm allows us submit form using Ajax.  The parameters say that when I click on the submit button please post this form using “Register” action on the “Home” controller which accepts “POST” request. After the form is submitted replace the contents of “ajaxForm” div with result of request and while you process the request display the loading image we specified earlier. 


2. Everything inside div form-horizontal is created using create a new asp.net mvc 4 view with a strongly typed model of type person. I modified the Birthdate field to take in the jquery ui date picker pay attention to the data_date attribute eg. data_date = "birthdate" we had inside the Register page.


Now we are going to see how everything clubs together. Until now you may be a bit lost. So lets check out our controller.  In the home controller create following methods.

           [HttpGet]
public ActionResult Register()
{
return View(new Person());
}

[HttpPost]
public async Task<PartialViewResult> Register(Person person)
{
await Task.Delay(1000);
if ((new string[] {"mitul1","mitul11","mitul12","mitul13"}).Contains(person.Username))
{
ModelState.AddModelError("Username", String.Format("username {0} is already taken", person.Username));
}
if (ModelState.IsValid)
{
return PartialView("_RegistrationResult");
}
return PartialView("_RegisterForm", person);
}

When you run the application and navigate to /Home/Register page it will hit the first Register method and display the Register.cshtml view. And inside Register.cshtml we have _RegisterFrom.cshtml partial view which will ultimately render the form.  After filling the form out when you click on the submit button the second Register method is called that takes in a Person object. This register method returns a PartialView in both the cases 1. if the form is successful 2. if the form has errors. Lets’ understand the second Register method in a little bit more detail.


1. This method uses async and await since you may be submitting the form to a database or checking validation against a web service asynchronously.  Special notice – See the async keyword on the method signature and because of that we cannot just return PartialViewResult we have decorate the method signature with Task<PartialViewResult>.  For demo purposes, I am using await Task.Delay(1000) instead of an async web call.


2. The first if statement checks if the username is already taken or not. This is just for demo purpose but you may have some complex validation on the server side and if any field is invalid then you want to throw that error back and the user should see it below that field. See the image below. You do that by using the ModelState.AddModelError method which takes in field name and error message. In our case we wanted to display that this username is already taken so we have specified ModelState.AddModelError(“username”,String.Format(”username {0} is already taken”,person.username);  Because of this statement our person model that was submitted by the user is invalidated and we return the same _RegisterForm.cshtml Partial view with person model.


image


3. If the model was valid then we enter into the second if statement and submit our person to a database or call a web service. Based upon you business logic you can do other things like if the form was unsuccessful show different message etc. In our case we are showing a partial view called _RegistrationResult.cshtml. You can modify this view to display either confirmation or error message.


Last but not the least to show stuff properly I am using following CSS.

#register-main{
position:relative;
border:3px solid green;
z-index:10;
}
#register-main-loading-img{
display:none;
position:absolute;
z-index:1;
top:0px;
left:0px;
width:100%;
height:100%;
border:3px solid orange;
background-color:rgba(216, 213, 213, 0.89);
}
#loading-img{
border:3px solid blue;
display:block;
position:relative;
width:100px;
height:100px;
margin-left:auto;
margin-right:auto;
top:50%;
}

 

So that’s about it. If you like this post of have any comments leave in the comments section.

 

 

Friday, September 18, 2015

Visual Studio Extension of the Week: Inline Color Picker

If you are a web developer then most modern IDE’s have this feature and thanks to Web Essentials and ReSharper I am used to seeing color next to their hex code counterpart inside Visual Studio. But if you are working in XAML then by default Visual Studio does not have this feature. In this post I want to mention a visual studio extension Inline Color Picker that displays actual color next to the hex code inside your XAML file. It allows you to pick a color of your choice using a color picker. I wonder why XAML team at Microsoft doesn’t add this feature.

image

image

Note this Extension has been there for Visual Studio 2015, 2013, 2012, 2010 all along.  Go download it if you are working with XAML.

Wednesday, September 2, 2015

Debugging your CSS selectors using Ctrl + F in F12 Chrome Developer Tools

Every once in a while I find myself writing a CSS selector and wonder why that style wasn’t applied to a particular element. While it is easy to just apply style attribute on that element and get the desired style you want but that isn’t recommended. Typically you want to be as specific as possible and the more specific you go, making sure you use the right CSS selector becomes very important.  The find element by CSS selector feature should be there in all modern browsers but I use Chrome for development so I will stick to Chrome.  This is not a new feature and most people should know already. 

Open Chrome developer tools window by pressing F12 while using Chrome on the site you are stuck debugging.  By default Element pane opens up and here you can do Ctrl + F and a very small textbox comes up. I wish this textbox was bigger and more prominent. See screenshot below.

Without find box.

image

With find box using Ctrl + F

image

Start typing your CSS selector and it will get highlighted in yellow as your element gets selected. In the screenshot below I am searching element with id=”main” as #main.

image

The most difficult CSS selectors to work with I have found are the ones which are nested and I don’t know why sometimes > sign will work or not. My personal rule of thumb is if I am doing a complex CSS selector then first try to find it in this textbox. If I can’t find my element highlighted here then don’t bother doing browser refresh exercise.  Another example

image

I may be showing really trivial examples here but it has helped me debug some complex CSS selectors with ease. If you know any tricks you love of F12 developer tools then please share in the comments section below.

Saturday, August 29, 2015

Visual Studio XAML tips and tricks

I am learning the new Universal Windows Application platform and along the way I learned these XAML editing features and I am sharing these as tips and tricks.

Tip 1 – Code formatting – Position each attribute on a separate line

As a personal preference I don’t like to scroll left and right just to see the all the attribute values of a XAML element. So to have each attribute value pair appear on a separate line you can go to Options > Text Editor > XAML > Formatting > Spacing  and select Position each attribute on a separate line. Enjoy.

image

Converts this

 image

into this

image

Tip 2 – View XAML Design page on one screen and XAML code page on another screen.

As a web developer I am so spoiled by always having code on one screen and browser on other screen. Edit code and hit refresh on other screen. I don’t like that XAML code and design page are stacked on top of each other. The view is very small and difficult to work with. I would love if there was an easy way to unpin the code and pin it to a secondary screen. 

Open your desired XAML file.  I am using MainPage.xaml. Its opens. Cool !! now to open it on the second screen right click your XAML page and Click on Open With option.

image

And then choose XML (Text) Editor option and XAML page will open. Now you should have same two files open and you can take the XAML page which as Design/XAML options available at the bottom like shown in screenshot below and double click on the Design option.  This will take the Design view to full screen but still have your XAML code window as is.

image

Now unpin the design window and drag and drop to second screen so when you edit your XAML code the design gets updated in real time on the second screen. I like this feature but this should be easier.

Tip 3 – Live Visual Tree

This is the best addition to Visual Studio 2015. While above two tips should work with older VS versions this one requires VS2015.  Just like F12 developer tools in browsers you can select any element by hovering mouse over it or select any element in the tree view to see which element is selected on the view you can do similar stuff with XAML now. My favorite thing in this feature is when you click on any element in the tree view and click on show properties then Properties window appears. The Properties window shows you all the properties that were applied to each element and you can change them and see the output in real time. You can also see some properties that are not applied or overridden as striked out.  Another cool thing with this feature is that as you select each element you can see XAML source view being updated. This is awesome.  Good job XAML team !!  I was able to fix my three column layout easily by using this feature.

If you know any cool XAML features that you love please share by leaving comments below.

Monday, March 16, 2015

String Extension to use instead of String.IsNullOrEmpty

Everyday while writing C# code until C# 6.0 comes I have to write code like this many times.

var firstName ="";
if(String.IsNullOrEmpty(firstName)){
"firstname is null or empty".Dump();
}

So one might ask what is wrong with this code. Nothing but it is not quite intuitive and readable. When you read, it doesn’t sound appropriate. I think that if(firstName.IsNullOrEmpty()) reads better and one doesn’t have to think of calling a static function.

public static class StringExtension
{
public static bool IsNullOrEmpty(this string value)
{
return String.IsNullOrEmpty(value);
}
public static bool IsNullOrWhitespace(this string value)
{
return String.IsNullOrWhiteSpace(value);
}
}
This allows us following.
if(firstName.IsNullOrEmpty())
{
"This reads much better.".Dump();
}

Sunday, March 1, 2015

PowerForms update - 0.3.4.16609

In the previous post, I introduced PowerForms Nuget package that allows you to create Windows Forms quickly using Fluent syntax. After publishing I have found some inconsistencies and found that certain methods are absurd. So in this post I am going to highlight what’s changed. 

How to get the update? If you are using it inside Console application then you can just install or update the package from Nuget Package Manager and using console use the following command.

Install-Package PowerForms –Version 0.3.4.16609

Changes

1. AutoSuggest method will no longer be supported in the next versions. You should be using separate overloads for doing the same. For example, If you want suggestions for TextBox then use TextBoxFor method that takes in IEnumerable<string>

  var form = new PowerForm();

var dt = form.TextBoxFor("FirstName",new string[]{"Mike","Molly","Manny","Maya"}).Display();

System.Console.WriteLine(dt["FirstName"].ToString());

2. Similarly if you now want to populate values for ComboBox then instead of using “Using” method use ComboBoxFor that takes IEnumerable<string>

 var form = new PowerForm();

var dt = form.ComboBoxFor("City",new List() { "Chicago", "Canton", "Cupcake" }).Display();

System.Console.WriteLine(dt["City"].ToString());

3. Calendar control was not obvious as how it was getting generated. So introducing CalendarFor method that will add a Calendar control.

var form = new PowerForm();

var dt = form.CalendarFor("Anniversary").Display();

System.Console.WriteLine(dt["Anniversary"].ToString());

I am very excited for PowerForms as this saves my so much of time within LinqPad. I have multiple queries that use PowerForms. It transforms LinqPad into a sophisticated tool. If you would like more features please suggest in the comments below and share how are you using PowerForms.

Sunday, February 1, 2015

Introducing PowerForms for creating windows form quickly

PowerForms is a little nuget package which allows you to create windows forms quickly either in a LinqPad query or in a console application for rapid data collection.

Before going into details of what PowerForms does let me tell you how it came into existence and what problem I was facing that PowerForms solves. Every once in a while I had to write certain queries either for debugging purposes or testing different scenarios that require different data inputs. After I wrote them I had to use them again and again with different input data which at first I had hardcoded.  For example, in a where clause WHERE lastname = ‘John’.  When you write a sql query in SQL Developer, LinqPad or SQL management studio you have to replace the text and run. This is a sample inside LinqPad using AdventureWorks data.

var person = Persons.Where(x => x.FirstName == "Mike" && x.LastName == "Choi").FirstOrDefault().Dump("Mike");
person.EmailAddresses.Dump("Email Addresses");
person.PersonPhones.Dump("Phones");
person.PersonCreditCards.Dump("Credit Cards");

I want to find a person by firstname of Mike and lastname of Choi. I am interested into other details of this person which I can quickly display once I get person object. This is why LinqPad is a very powerful software. Now some other time you might be interested into another person and I don’t want to replace the text. I don’t to put anything in the query.  I want a form into which I can quickly supply details and I can see details into LinqPad using our favorite Dump method.  With SQL Developer and SQL Management Studio you can customize. Hence I experimented with displaying a windows form from LinqPad. 


“Oh wait. You said Windows Form!! Really?” Yes my friend. A windows form from within LinqPad.


“Wow”. 


LinqPad is very powerful and it has become my daily companion for quick debugging, snippet evaluation, rapid prototyping and more. Sorry LinqPad some other day. This post is for PowerForms.


With PowerForms you can quickly create a form that will allow you to collect data as shown in the image below. I want to collect FirstName and LastName and the above query uses that FirstName and LastName.


image


So how to use it and where to get it. You can get PowerForms as a nuget package and add it to either LinqPad or even your console application. Primarily I intended it to be used inside of LinqPad but after I realized that it could be used inside console application just fine. And there are advantages to that too which I have mentioned below. Here is a quick way of creating a form shown in the above image using a fluent syntax.

var form = new PowerForm();
var fd = form.TextBoxFor("FirstName").TextBoxFor("LastName").Display();
var firstName = fd["FirstName"].ToString().Dump("Firstname");
var lastName = fd["LastName"].ToString().Dump("LastName");

image


Let’s dive into the details of the above example. First we create a new PowerForm() and on the form object we can specify what we want in our form. In this case, we specify we want TextBox for “FirstName” and then another one for “LastName” and then display the form using .Display() method. The .Display() method returns a dictionary of type string and object. The values you provide in the form are stored inside Dictionary<string,object>. To retrieve FirstName we would do fd[“FirstName”].ToString();.


Now some examples and fun.


1. Create a single TextBox using TextBoxFor

 var dt = form.TextBoxFor("FirstName").Display();

2. Create multiple TextBoxes using different syntaxes

 var dt = form.TextBoxFor(new string[]{"FirstName","LastName"}).Display();
//or

var fd = form.TextBoxFor("FirstName")
.TextBoxFor("LastName")
.Display();

3. Display a Calendar Control for selecting Date

  var dt = form.TextBoxFor("StartDate").Display();
image

4. Display a Calendar Control & TextBox for selecting Date

  var dt = form.TextBoxFor(new string[] { "Birthdate", "LastName" }).Display();

image


5. Lets do something even more. Create a ComboBox using the string array.



var dt = form.ComboBoxFor("City")
.Using(new List<string>() { "Chicago", "Canton", "Cupcake" })
.Display();



image

6. I know you are still not impressed or convinced in this silly utility. Let do auto suggestion for a textbox. In the using method you can even specify from a list or another query. Very powerful.



var dt = form.AutoSuggest("FirstName")
.Using(new string[]{"Mike","Molly","Manny","Maya"})
.Display();

image


7. You can do multiple of these Auto Suggest textboxes



var dt = form.AutoSuggest("FirstName").Using(new string[] { "Mike", "Molly", "Manny", "Maya" })
.AutoSuggest("LastName").Using(new string[] { "Suthar", "SutherLand", "So", "Sue", "Summer" })
.Display();

image


8. Here is full combination of options you can try it out.

	var dt = form.AutoSuggest("FirstName").Using(new string[] { "Mitul", "Mike", "Michael", "Manny" })
.AutoSuggest("LastName").Using(new string[] { "Suthar", "SutherLand", "So", "Sue", "Summer" })
.AutoSuggest("MiddleName").Using(new string[] { "Parry", "Pari", "Pom", "Pommy" })
.ComboBoxFor("Country").Using(new string[] { "USA", "CHINA", "INDIA", "INDONESIA" })
.ComboBoxFor("Cities").Using(new List<string>() { "Chicago", "Canton", "Cupcake" })
.TextBoxFor(new string[] { "BirthDate", "Hello", "World" })
.Display();

image


9. Bonus. Sometimes you might want to show confirmation before doing something

            var dt = form.ComboBoxFor("City").Using(new List<string>() { "Chicago", "Canton", "Cupcake" }).Display();
var shouldContinue = form.DisplayConfirmation();
if (shouldContinue)
{
"You selected to continue..".Dump();
dt["City"].Dump();
}

image


In the above example, after you display the first time then it displays a confirmation dialog. I have found PowerForms very useful in doing some daily work. 


“So what kind of things you do with PowerForms Mitul?”


Like every enterprise, we have big ERP system with hundreds of tables and I have to write queries to make sense of that data. I have created a query powered by PowerForms where I can find a user with multiple attributes. Once the PowerForm is displayed I can just type in either FirstName or userid or anything and hit submit and bingo I get my results. 


Another scenario where I use is testing web services against different uris and I have created a PowerForm with ComboBox for different Uris and related endpoints with parameters as textboxes. I save time by not having to change anything in these queries once I write them. In essence whenever you need to collect data.


“Can I run PowerForms in a console application?”


Yes.


In order to use PowerForms in a console application you will have to decorate the Main method with [STAThread] and then it will work just fine. It will open a console and PowerForm. If you change the output type of console application  to Windows Application then it will not show you console window and only a PowerForm. This way you can create a quick utility application and put it on your network share drive for others to use. The users don’t have to install the application.


PowerForms has made my LinqPad instance a Power ERP system. PowerForms is not intended as a replacement for Windows Forms. That would be silly. However for scenarios I just mentioned it serves its purpose pretty well.


What do you guys think of PowerForms? If you have any suggestions, questions, comments please let me know in the comments section.