Friday, 22 February 2013

LightSwitch: Add Non Existent Records Using AutoCompleteBox

The LightSwitch AutoCompleteBox allows you select records using a dropdown list or to enter some text into the control. Typing into the AutoCompleteBox filters down the selectable records.

If a non existent record entered, it’s likely that a new record is required based upon the entered text. 

The following example uses a set of Customer and Category tables. A Customer belongs to a Category and the following sample demonstrates a ‘New Data Screen’ for creating a new Customer. The screen contains an AutoCompleteBox which allows a category to be selected. If a non existent category is typed in, the user will be prompted to save the new category prior to saving the customer record.

Code:

We need to write some code to handle the LostFocus event of the AutoCompleteBox. However, this can only be done when the AutoCompleteBox becomes available. We therefore need to write an event handler for the ‘ControlAvailable’ event and to add the handler for the LostFocus event there. Click on the ‘Write Code’ button and click and select the ‘CreateNewCustomer_Created’ event. Add the following code:


private void CreateNewCustomer_Created()
{
    this.FindControl("Category").ControlAvailable += CategoryFieldAvailable;
}

private void CategoryFieldAvailable(object sender, ControlAvailableEventArgs e)
{
    ((System.Windows.Controls.Control)e.Control).LostFocus += CategoryFieldChanged;
}


private void CategoryFieldChanged(object sender, System.Windows.RoutedEventArgs e)
{
    //Add a reference to System.Windows.Controls.Input.dll in the Client project
    string txtComboText = ((System.Windows.Controls.AutoCompleteBox)sender).Text;
    this.Details.Dispatcher.BeginInvoke(() =>
    {
        if (!string.IsNullOrEmpty(txtComboText)) {
            Category selectedCategory = this.DataWorkspace.ApplicationData.Categories.Where(Category => Category.CategoryName == txtComboText).FirstOrDefault;
            if (selectedCategory == null) {
                //Category doesn't exists
                if (this.ShowMessageBox("Do you want to add the category " + txtComboText + "?", "Add Category", MessageBoxOption.YesNo) == System.Windows.MessageBoxResult.Yes) {
                    selectedCategory = this.DataWorkspace.ApplicationData.Categories.AddNew();
                    selectedCategory.CategoryName = txtComboText;
                    this.CustomerProperty.Category = selectedCategory;
                }
            }
        }
    });

}
 
In the above code, we obtain the text that has been entered using the 
‘Text’ property of the AutoCompleteBox. If the text is not empty, we 
attempt to look up the Category in the Category table. If the Category 
isn’t found, we use ‘ShowMessageBox’ to prompt the user to save the new 
Category. After the new Category is saved, we set the Category property 
on the Customer entity equal to the Category which has just been 
created.
 
Now run the application. Here are some illustrations showing the 
application in action. We begin by having just a ‘High Risk’ Category in
 the database. 
In the ‘Create New Customer’ form, we enter a Firstname, Surname and type ‘Low Risk’ into the Category AutoCompleteBox. When we leave the Category AutoCompleteBox, the following dialog appears.
 
If we click ‘Yes’, the Customer record is saved into the database. If we
 now return to the Category screen, we see that the ‘Low Risk’ category 
has also been added into the database. 
 
 
Your new entry has been saved.
 
LightSwitch: Textbox LostFocus Event  

Sunday, 17 February 2013

In What Order do Screen Events Fire?

Overview of Article

There are various screen events available in LightSwitch. At the moment, there isn’t very much documentation specifying the order in which these events fire.
The following post documents my findings in relation to the ordering of events.

Methodology

Having created a details screen based on a ‘Customer’ entity, this is a typical screen which is created by default. The name of the screen is ‘CustomerDetail’ and the name of the Customer entity is ‘Customer’.

The following screenshot shows the available events. There are 3 property/entity events and 7 screen events. ‘CustomerId’ is the name of the property that relates to the screen parameter.


In order to work out the order in which these events fire, I’ve written some code showing a message box on each event. Here are my findings:

Order of events when opening a screen

  1. New
  2. CustomerId_Changed
  3. CustomerDetail_InitializeDataWorkspace
  4. CustomerDetail_Created
  5. CustomerDetail_Activated
  6. Customer_Validate
  7. CustomerId_Validate
  8. Customer_Loaded

Order of Events when changing a field and clicking ‘Save’

  1. CustomerDetail_Saving
  2. Customer_Validate
  3. CustomerId_Validate
  4. Finalize

Order of Events when closing a screen with no changes

  1. CustomerDetail_Closing
  2. Finalize

Order of Events when closing a screen with unsaved changes and choosing to discard

  1. CustomerDetail_Closing
  2. Finalize

Order of Events when closing a screen with unsaved changes and choosing to save

  1. CustomerDetail_Closing
  2. CustomerDetail_Saving
  3. Customer_Validate
  4. CustomerId_Validate
  5. Finalize
As a final note, the CustomerDetail_Activated will fire whenever you change focus to another screen and return to it. Hopefully, this post sheds a bit more light into the ordering of events.

For more detailed screen shots please click here

Saturday, 16 February 2013

How to: Execute a Stored Procedure in LightSwitch

The Database
For this example, we are going to use the AdventureWorks sample database. The AdventureWorks database has a “HumanResources” schema that stores information about your company’s organization, employees, and job candidates. The AdventureWorks database has a stored procedure that allows an application to update an Employee’s personal information. One of these pieces of information is the employee’s marital status. Here is what the stored procedure looks like:

CREATE PROCEDURE [HumanResources].[uspUpdateEmployeePersonalInfo]
@EmployeeID [int], 
@NationalIDNumber [nvarchar](15), 
@BirthDate [datetime], 
@MaritalStatus [nchar](1), 
@Gender [nchar](1)
WITH EXECUTE AS CALLER
AS
BEGIN
SET NOCOUNT ON;
UPDATE [HumanResources].[Employee] 
SET [NationalIDNumber] = @NationalIDNumber 
,[BirthDate] = @BirthDate 
,[MaritalStatus] = @MaritalStatus 
,[Gender] = @Gender 
WHERE [EmployeeID] = @EmployeeID;
END;

Table view

C#:
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
    
public partial class ApplicationDataService
{
    partial void UpdatePersonalInfoOperations_Inserting(UpdatePersonalInfoOperation entity)
    {
        using (SqlConnection connection = new SqlConnection())
        {
            string connectionStringName = this.DataWorkspace.AdventureWorksData.Details.Name;
            connection.ConnectionString =
                ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;

            string procedure = "HumanResources.uspUpdateEmployeePersonalInfo";
            using (SqlCommand command = new SqlCommand(procedure, connection))
            {
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.Add(
                    new SqlParameter("@EmployeeID", entity.EmployeeID));
                command.Parameters.Add(
                    new SqlParameter("@NationalIDNumber", entity.NationalIDNumber));
                command.Parameters.Add(
                    new SqlParameter("@BirthDate", entity.BirthDate));
                command.Parameters.Add(
                    new SqlParameter("@MaritalStatus", entity.MaritalStatus));
                command.Parameters.Add(
                    new SqlParameter("@Gender", entity.Gender));

                connection.Open();
                command.ExecuteNonQuery();
            }
        }

        this.Details.DiscardChanges();
    }
}


VB:
Imports System.Configuration
Imports System.Data
Imports System.Data.SqlClient

Namespace LightSwitchApplication
    Public Class ApplicationDataService
        Private Sub UpdatePersonalInfoOperations_Inserting(entity As UpdatePersonalInfoOperation)
            Using connection = New SqlConnection
                Dim connectionStringName = Me.DataWorkspace.AdventureWorksData.Details.Name
                connection.ConnectionString =
                    ConfigurationManager.ConnectionStrings(connectionStringName).ConnectionString

                Dim procedure = "HumanResources.uspUpdateEmployeePersonalInfo"
                Using command = New SqlCommand(procedure, connection)
                    command.CommandType = CommandType.StoredProcedure

                    command.Parameters.Add(
                        New SqlParameter("@EmployeeID", entity.EmployeeID))
                    command.Parameters.Add(
                        New SqlParameter("@NationalIDNumber", entity.NationalIDNumber))
                    command.Parameters.Add(
                        New SqlParameter("@BirthDate", entity.BirthDate))
                    command.Parameters.Add(
                        New SqlParameter("@MaritalStatus", entity.MaritalStatus))
                    command.Parameters.Add(
                        New SqlParameter("@Gender", entity.Gender))

                    connection.Open()
                    command.ExecuteNonQuery()
                End Using
            End Using

            Me.Details.DiscardChanges()
        End Sub
    End Class
End Namespace 

Creating a Button to Call Our Operation

Now let’s invoke this middle tier operation.  We wish to add a button to our application that will mark a Single employee as Married. First, open the SearchEmployees screen and add a new button to the ribbon. At the top of the screen designer, right-click the “Screen Command Bar” content item and select “Add Button…”.
 
 
Name the button “MarkAsMarried”. We only want this button to be enabled for single employees, so right-click the button and select “Edit CanExecute Code”. Enter in the following code:

C#:
partial void MarkAsMarried_CanExecute(ref bool result)
{
    result = this.Employees.SelectedItem != null && 
        this.Employees.SelectedItem.MaritalStatus == "S";
}
VB:
Private Sub MarkAsMarried_CanExecute(ByRef result As Boolean)
    result = Me.Employees.SelectedItem IsNot Nothing And
        Me.Employees.SelectedItem.MaritalStatus = "S"
End Sub
Back in the screen designer, right-click on the button again and select “Edit Execute Code”.  Enter the following code:
C#:
partial void MarkAsMarried_Execute()
{
    DataWorkspace dataWorkspace = new DataWorkspace();
    Employee employee = this.Employees.SelectedItem;

    UpdatePersonalInfoOperation operation = 
        dataWorkspace.ApplicationData.UpdatePersonalInfoOperations.AddNew();
    operation.EmployeeID = employee.EmployeeID;
    operation.NationalIDNumber = employee.NationalIDNumber;
    operation.BirthDate = employee.BirthDate;
    operation.MaritalStatus = "M";
    operation.Gender = employee.Gender;

    dataWorkspace.ApplicationData.SaveChanges();
}
VB:
Private Sub MarkAsMarried_Execute()
    Dim dataWorkspace = New DataWorkspace
    Dim employee = Me.Employees.SelectedItem

    Dim operation =
        dataWorkspace.ApplicationData.UpdatePersonalInfoOperations.AddNew()
    operation.EmployeeID = employee.EmployeeID
    operation.NationalIDNumber = employee.NationalIDNumber
    operation.BirthDate = employee.BirthDate
    operation.MaritalStatus = "M"
    operation.Gender = employee.Gender

    dataWorkspace.ApplicationData.SaveChanges()
End Sub

This code first creates a new DataWorkspace.  This is needed because we don’t want to modify the current change set on the screen.  Instead, we will make an independent change set that only contains the operation entity we wish to invoke.  When it is complete, we discard the DataWorkspace and operation entity.
Next, we create a new UpdatePersonalInfoOperation making sure to use our newly created DataWorkspace’s ApplicationData.  We grab the currently selected employee’s information and set it on the operation, but we tell the operation to change the MaritalStatus to “M”.  Finally, we invoke the operation by calling SaveChanges.
That’s it.  Now you can run your application, select a single employee, and click on the Mark As Married button.  The stored procedure will be invoked.
 
Second Method to use the store procedure

1. Create a class file in server folder under UserCode


2. Write the following code in that file


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace LightSwitchApplication.UserCode
{
   public class SqlHelper
    {
        public static SqlConnection conn(string Connection)
        {
            SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings[Connection].ConnectionString);
            return con;
        }
        public static void InsInFeeDeatil(Int64 StuID, string CreatedBy,string ConnectionString)
        {
            string SP = "spInsFeeStructure";
            SqlCommand cmd = new SqlCommand();
            SqlConnection con = conn(ConnectionString);
            cmd.Connection = con;
            cmd.CommandText = SP;
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add(new SqlParameter("@StuID",StuID ));
            cmd.Parameters.Add(new SqlParameter("@CreatedBy",CreatedBy));
            con.Open();
            cmd.ExecuteNonQuery();
          
        }
    }
}
Now write the following code under mail class file under inserting function
partial void tbStudentMasters_Inserting(tbStudentMaster entity)
        {
            SqlHelper.InsInFeeDeatil(StuId+1, this.Application.User.Name,this.DataWorkspace.SMData.Details.Name);
        }

The above code automatically fire when you are trying to insert the new entry in the data base


Allowing certain users to update personal information

A lot of times, you only want specific people to be able to invoke the stored procedure.  Using the pattern above, it is very simple to enable this in your application.  First, start by creating a Permission by navigating to the Application’s Properties (right-click on the application in the Solution Explorer and select “Properties” or double click the “Properties” item under the application).  On the “Access Control” tab, enable authentication and enter a new Permission in the grid.

Now, to only allow users with the UpdatePersonalInfo permission to invoke the stored procedure, we just need to say that only these users are allowed to “insert” the UpdatePersonalInfoOperation records.  So go back to the UpdatePersonalInfoOperation entity and drop down “Write Code” –> UpdatePersonalInfoOperations_CanInsert and enter the following code:

C#:
partial void UpdatePersonalInfoOperations_CanInsert(ref bool result)
{
    result = this.Application.User.HasPermission(Permissions.UpdatePersonalInfo);
}
VB:
Private Sub UpdatePersonalInfoOperations_CanInsert(ByRef result As Boolean)
    result = Me.Application.User.HasPermission(Permissions.UpdatePersonalInfo)
End Sub

Now if a user isn’t granted the UpdatePersonalInfo permission, and they try invoking this operation, it will throw a PermissionException and not allow the user to perform the operation.  This isn’t a great user experience, so the last thing to change in the application is the button’s CanExecute code to check if the current user has permission to insert UpdatePeronalInfoOperation records.  Change your button’s CanExecute method as follows:

C#:
partial void MarkAsMarried_CanExecute(ref bool result)
{
    result = this.Employees.SelectedItem != null &&
        this.Employees.SelectedItem.MaritalStatus == "S" &&
        this.DataWorkspace.ApplicationData.UpdatePersonalInfoOperations.CanInsert;
}
VB:
Private Sub MarkAsMarried_CanExecute(ByRef result As Boolean)
    result = Me.Employees.SelectedItem IsNot Nothing And
        Me.Employees.SelectedItem.MaritalStatus = "S" And
        Me.DataWorkspace.ApplicationData.UpdatePersonalInfoOperations.CanInsert
End Sub
 
Thanks Eric Erhardt 

The specified module could not be found. (MS Visual Database Tools)

The specified module could not be found. (MS Visual Database Tools)

While working in Microsoft SQL Server Management Studio, I came across an unwanted "The specified module could not be found. (MS Visual Database Tools)" when selecting to create a new 'Database Diagram'.




After so many googling on google I found one solution and it is working for me.For this solution you have to change some files on your system.
Follow the following steps 

 C:\Program Files (x86)\Common Files\microsoft shared\MSDesigners8 (64 bit)
  
Click here to Download.

For 32 bit please find the same folder under Program Files.

More search 

Download Shortcuts

Friday, 15 February 2013

Filter Items in an Auto Complete Box or Modal Window Picker in LightSwitch

How Do I: Filter Items in an Auto Complete Box or Modal Window Picker in LightSwitch

As with most application platforms, it is possible to associate related pieces of data in Visual Studio LightSwitch. A classic example is a SalesOrder is associated with the Customer that placed the order.
 


When a sales order entry clerk is entering a new sales order into the system, normally the sales application will allow the clerk to select the Customer that is placing the order. In LightSwitch, there are two built-in UI controls to associate one record with another:
· Auto Complete Box
· Modal Window Picker
Which one you choose is dependent on your user experience needs. As a rule of thumb, for most data sets, I would use the Auto Complete Box.  This control allows for quick data entry by the end user.  The user can just begin typing, and the intended record is selected automatically.  For data sets that are going to grow to hundreds, maybe thousands, of items it is appropriate to use the Modal Window Picker.  The Modal Window Picker allows the end user to search and sort the items in order to find the correct record. By default, LightSwitch will choose the Auto Complete Box control.

Out of the box, these picker controls will show all of the records in a table. But there are plenty of cases where an application would want to filter which records are shown in the picker. For example, in our SalesOrder-Customer scenario above, we would like the system to track active and inactive Customers. Although the inactive Customer records are still in the system, a new SalesOrder should not be created to associate to an inactive Customer.

In order to accomplish this, we start by creating a New Data Screen based on the SalesOrder table.



In the newly created screen, notice that there is an Auto Complete Box control for the Customer that placed 
this SalesOrder.



We want to define a query that will filter out the inactive Customers from this picker. In order to do this, click the Add Data Item button at the top of the designer.


In the Add Data Item dialog, select the Query radio button, and the Customers query in the query list. Name this new data item “ActiveCustomers” and click OK.

.


This will create a new ScreenCollectionProperty named “ActiveCustomers” on the left side of the screen designer. In order to change the filter on this query, click the Edit Query hyperlink next to ActiveCustomers.


This will launch the query designer where you can specify the filter. Add a new filter “Where IsActive = ‘True’” and sort by “Name Ascending”.


Alternatively, instead of defining the query directly on the screen, you can add a new Query under the Customers table in the Solution Explorer. This allows you to reuse the query across multiple screens. To do this, right-click the Customers table in the Solution Explorer and select “Add Query”. Name the query “ActiveCustomers” and define the filter and sort as above. In the screen designer, instead of picking the “Customers (All)” query, select the “ActiveCustomers” query that was just created.
Now all that is left is to hook up the Customer picker control with this newly created query. Return to the CreateNewSalesOrder screen designer by clicking the Back arrow at the top left of the query designer. Find the “Customer” content item in the screen tree, select it and open the Properties sheet by pressing F4. In the Properties sheet, you will see a “Choices” property with a drop down. Open the Choices drop down and select the “ActiveCustomers” property that was created.


That’s it! Now you can press F5 to launch the application and open the CreateNewSalesOrder screen to create a new sales order. When attempting to select the customer for the new sales order, the user will only be allowed to pick active customers.

Modal Window Use In LightSwitch

Use Modal Window to add and edit records in the lightswitch

1 In your screen Add new group, it will Add Rows layout change it to be modal window "this window will hold your screen for add/edit" Rename this modal window to be AddEditCustomer
2 Change its Is Visible property to false
3 In its command bar Add new button twice one will be btnOk, the other will be btnCancel, then Below it drag the Customers query
4 Add property of type Customer to the designer call it NewCustomer
5 Point to your Customers list or grid command bar right click on Add button and select Edit Execute Code, do the same for Edit Button
the 2 functions code should be like this :
 
partial void CustomerListAddAndEditNew_Execute()
        {
            // Write your code here.
            NewCustomer = new Customer();
            this.OpenModalWindow("AddNewCustomer");
            this.FindControl("AddNewCustomer").ControlAvailable += new EventHandler<ControlAvailableEventArgs>(NewCustomer_WindowAvailable);
        }
partial void CutomerListEditSelected_Execute()
        {
            // Write your code here.
            NewCustomer = this.Customers.SelectedItem;
            this.OpenModalWindow("AddNewCutomer"); // modal window name
            this.FindControl("AddNewCutomer").ControlAvailable += new EventHandler<ControlAvailableEventArgs>(NewCusomr_WindowAvailable);
        }

void NewCustomer_WindowAvailable(object sender, ControlAvailableEventArgs e)

{



this.FindControl("AddNewCustomer").ControlAvailable -= new EventHandler<ControlAvailableEventArgs>(NewCustomer_WindowAvailable);



((ChildWindow)e.Control).Closed += new EventHandler(NewCustomer_Closed);



}

void NewCustomer_Closed(object sender, EventArgs e)

        {



            ((ChildWindow)sender).Closed -= new EventHandler(NewCustomer_Closed);



            if (!((ChildWindow)sender).DialogResult.HasValue)

                 CancelAddCustomerChanges();

               CloseAddCustomerWindow();



        }

private void CloseAddCustomerWindow()

        {

             this.CloseModalWindow("AddNewCustomer");

           

        }

        private void CancelAddCustomerChanges()

        {

            NewCustomer.Details.DiscardChanges();

        }

partial void btnOk_Execute()

        {

            // Write your code here.

            this.Customers.SelectedItem = this.NewCustomer;

            CloseAddCustomerWindow();

        }



        partial void btnCancel_Execute()

        {

            // Write your code here.

            CancelAddCustomerChanges();

            CloseAddCustomerWindow();

        }

partial void btnSubmit_CanExecute(ref bool result)

        {

            // Write your code here.

            result =  NewCustomer!= null && NewCustomer.CustomerName!=null && Any Mandatory Field in Customer entity!=null;

        }

Saturday, 9 February 2013

Sql Server DataTypes

SQL Server Data Types Reference

Introduction

 There are plenty of data types to use in SQL Server. Knowing the limitations and benefits of each one will soon pay off. For instance, choosing the tinyint datatype instead of the int datatype for the "ProductType" column with values ranging from 1 to 10 will save three bytes per record. With 100,000 records you will save 300,000 bytes. That's not much in terms of disc space ("storage is cheap, bla bla") but you'll probably have indexes containing that column and if that index takes less memory the engine will process that index much faster in every "join" and "where" etc. So those queries will perform better and use less system resources (memory) which will make the whole server perform better as there will be more resources available for other things. Once learned the datatypes available and spending a few extra minutes when designing your schema will result in faster query execution and a better performing database.

This sheet provides an easy reference to look up limitations and benefits for each SQL Server data type.

The Data types reference sheet

The columns 8, 9, 10 shows what versions of SQL Server that supports the data type
  • 8 = SQL Server 2000
  • 9 = SQL Server 2005
  • 10 = SQL Server 2008

Saturday, 2 February 2013

LightSwitch: Textbox LostFocus Event

The LightSwitch AutoCompleteBox allows you select records using a dropdown list or to enter some text into the control. Typing into the AutoCompleteBox filters down the selectable records.

If a non existent record entered, it’s likely that a new record is required based upon the entered text. 

The following example uses a set of Customer and Category tables. A Customer belongs to a Category and the following sample demonstrates a ‘New Data Screen’ for creating a new Customer. The screen contains an AutoCompleteBox which allows a category to be selected. If a non existent category is typed in, the user will be prompted to save the new category prior to saving the customer record.

Code:

We need to write some code to handle the LostFocus event of the AutoCompleteBox. However, this can only be done when the AutoCompleteBox becomes available. We therefore need to write an event handler for the ‘ControlAvailable’ event and to add the handler for the LostFocus event there. Click on the ‘Write Code’ button and click and select the ‘CreateNewCustomer_Created’ event. Add the following code:


private void CreateNewCustomer_Created()
{
    this.FindControl("Category").ControlAvailable += CategoryFieldAvailable;
}

private void CategoryFieldAvailable(object sender, ControlAvailableEventArgs e)
{
    ((System.Windows.Controls.Control)e.Control).LostFocus += CategoryFieldChanged;
}


private void CategoryFieldChanged(object sender, System.Windows.RoutedEventArgs e)
{
    //Add a reference to System.Windows.Controls.Input.dll in the Client project
    string txtComboText = ((System.Windows.Controls.AutoCompleteBox)sender).Text;
    this.Details.Dispatcher.BeginInvoke(() =>
    {
        if (!string.IsNullOrEmpty(txtComboText)) {
            Category selectedCategory = this.DataWorkspace.ApplicationData.Categories.Where(Category => Category.CategoryName == txtComboText).FirstOrDefault;
            if (selectedCategory == null) {
                //Category doesn't exists
                if (this.ShowMessageBox("Do you want to add the category " + txtComboText + "?", "Add Category", MessageBoxOption.YesNo) == System.Windows.MessageBoxResult.Yes) {
                    selectedCategory = this.DataWorkspace.ApplicationData.Categories.AddNew();
                    selectedCategory.CategoryName = txtComboText;
                    this.CustomerProperty.Category = selectedCategory;
                }
            }
        }
    });

}
 
In the above code, we obtain the text that has been entered using the 
‘Text’ property of the AutoCompleteBox. If the text is not empty, we 
attempt to look up the Category in the Category table. If the Category 
isn’t found, we use ‘ShowMessageBox’ to prompt the user to save the new 
Category. After the new Category is saved, we set the Category property 
on the Customer entity equal to the Category which has just been 
created.
 
Now run the application. Here are some illustrations showing the 
application in action. We begin by having just a ‘High Risk’ Category in
 the database. 

In the ‘Create New Customer’ form, we enter a Firstname, Surname and type ‘Low Risk’ into the Category AutoCompleteBox. When we leave the Category AutoCompleteBox, the following dialog appears.


 
If we click ‘Yes’, the Customer record is saved into the database. If we
 now return to the Category screen, we see that the ‘Low Risk’ category 
has also been added into the database.