Skip to content

Wrench in the Cog

Throwing a wrench into the cogs of a programmer's life

Archive

Category: Software Development

This post extends my last post where I created a new Schedule table and then created a relationship between that and my Customer table. Now I want to make my application a bit more effective and efficient by creating a query to help me better visualize my scheduling data.

(Thank you Beth Massi, those video tutorials walk-through posts are fantastic!)

What is a LightSwitch Query?

A query is something that returns a bunch of date based on some criteria or filter. In LightSwitch, queries can be created and then used for screens or even in code. I want to use queries as a way of better getting only the data I need to immediately see. More specifically, I want to create a query that will only provide me with scheduling information for today, as well as a query for scheduling information in the future.

I don’t really need to see past scheduling, because I don’t live in the past, although I do learn from it; hence how proficient I have become at software development (yes, I’ve made a LOT of mistakes…in the past…I’m perfect now! ). So, with my superior skill of learning from my mistakes, I will make a whole bunch of mistakes during this demonstration – and learn from them. I am going to create a query that will only return schedule items that are scheduled in the future.

Creating a Query

In LightSwitch, when a query is created, it is added to the application model, meaning that the query is essentially baked into the design of the entity the query is created for. For what I want to achieve, I need to create a query on my collection of Schedule records.

In my LightSwitch application Solution Explorer I expand the Application Data node of the Data Sources folder. I right-click on my Schedules collection and click the Add Query menu item.

Adding a query to my Schedules collection

Adding a query to my Schedules collection

LightSwitch opens a query designer window for a query titled Query1. I immediately rename this query to FutureSchedule.

Updated query name and display name in query designer

Updated query name and display name in query designer

With that out of the way, I now need to add some criteria to my query.

Filter Conditions

I want to only display schedule items that are either for today, or in the future. To do this, I am going to add a filter condition to the query. A filter condition is what helps narrow my query results. In this case, I am going to filter my query results to only display schedule items that have a date of today or greater.

So, I click on the Add Filter link.

Click the Add Filter button

Click the Add Filter button

Clicking the Add Filter button presents me with a filter criteria where I can enter the conditions of my filter.

The Filter Condition

The Filter Condition

In the first drop down I have an option to select a value of Where or Where Not. The condition I want is to return records where there is a StartDateTime value that is greater than or equal to today’s date. So, I;

  • select Where from the first drop down,
  • then select StartDateTime from the second drop down, which is a list of the attributes of the Schedule entity,
  • select the greater than or equal to operator value in the next drop down, And
  • …select…wait a minute. I see a problem, can you see a problem?

Hmm, I immediately see that there is going to be an issue here. My requirement is to filter using a value that will change day to day. I can’t simply stick a comparison to a literal date in there because the day is going to change each day.

Looking more at that list of comparison values, I see an item named Parameter. This might be how I can solve this problem. If I can somehow pass the current date to the query, and then have the query use that date as a comparison value, the query should be able to filter correctly with each passing day. Let’s give a go shall we then?

For now, I am going to select Literal as the comparison value, and leave the defaulted value in the filter condition. I’ll update this condition once I have my parameter all set up.

My temporary filter condition

My temporary filter condition

Parameters

Parameters are a way of passing values to a query when the application is running. For me, I want to pass the current date as a parameter to the query, and then have the query use that parameter as the filter condition.

In the query designer, I click the Add Parameter button.

Click the Add Parameter button

Click the Add Parameter button

Clicking the Add Parameter button presents me with a textbox and and parameter type dropdown box. I enter StartDateTimeParameter as the name of my parameter, and select DateTime as the type of parameter.

The StartDateTimeParameter Parameter

The StartDateTimeParameter Parameter

In the Properties window for the parameter, I update the Display Name property to  Schedule From so that if I ever have a need to be prompted for a parameter, the prompt will be better named.

Cool, now that I have my property created, I go an update the filter I previously created so that it will use the parameter value instead of a literal value.

Updated Filter Condition

Updated Filter Condition

One more tweak left -sorting

Sorting

I want to make sure that query results show my most recent schedule. I need to order the results by StartDateTime, in ascending order.

No problem, I click the Add Sort button in the query designer window.

My Sort criteria

My Sort criteria

I select StartDateTime as the field I want to sort on, and then select Ascending as the order by which I want to sort the field.

The Screen

Are you sitting comfortably? Then we’ll being…

Armed with my query, I now want to create a screen that shows my my query results. So, on the menu bar at the top of the query designer, I click the Add Screen… button.

Click the Add Screen button

Click the Add Screen button

A simple list of scheduled items is all I need, so in the Add New Screen window I select the Editable Grid Screen template.  LightSwitch defaults a Screen Name of EditableScheduleGrid, which is fine. Then from the Screen Data drop down box I select the Schedule query I just created. I click the OK button.

Creating the screen for the query

Creating the screen for the query

LightSwitch opens the screen designer for my new EditableScheduleGrid screen. The first thing I do is update the Display Name property for the screen to say My Schedule

Changing the Display Name for the screen

Changing the Display Name for the screen

Almost there. I need to now somehow get the current date to the parameter for use by the query. To do that, I have to first create a property for my screen to hold the date.

When LightSwitch created my new screen it recognized that the data for the screen is my query. LightSwitch also saw that there is a parameter for the query, so it added the parameter as a property of the screen. I can see this because it is listed on the left of the designer.

Parameter query, and screen property showing in designer

Parameter query, and screen property showing in designer

I like how this is done automagically. I still need to wire the parameter to the screen property. This is easy, all I do is click the screen property (StartDateTimeParameter in grey), and LightSwitch wires the two together – as shown by the little arrowed line connecting the two.

Query parameter and screen property wired together

Query parameter and screen property wired together

With the StartDateTimeParameter screen property selected, I notice that the Property Type for the StartDateTimeParameter screen property is shown as a DateTime? value. Not sure what it means if that value has a question mark on the end of it, so I select the DateTime value (without the question mark).

Updating the StartDateTimeParameter property type

Updating the StartDateTimeParameter property type

Okay, now to get that date in there.

There are two things that I need to do next. The first is to call the screen to open it, and the pass the parameter to the screen that I am opening. So, I open the screen designer for the screen I know will open first in the application. In this case, the screen is named CustomerList.

I open the CustomerList screen in the screen designer. In the screen designer I expand the Screen Command Bar tree node and click the Add button. I then click to add a New Button.

Adding a new button to the screen command bar.

Adding a new button to the screen command bar.

Now I have a new button that will show up at the top of the screen when the application runs. I need to now set some properties on this button so it shows up all nice like.

With the new button selected, I head over to the properties pane and make some edits. I enter My Schedule in the Display Name property.

Updates to the new button properties

Updates to the new button properties

Over on the left of the designer, I see the Button object added to my screen.

The Button object

The Button object

I click on it to view the properties of the object. I edit the Method Name property to say ShowMySchedule. Below that, I click the Edit Execute() Code link.

The new Method Name for the button, and the Edit Execute() Code link

The new Method Name for the button, and the Edit Execute() Code link

LightSwitch opens the CustomerList.vb code window for with a stub created for my new method.

Namespace MyFirstApplication

  Public Class CustomerList

    Private Sub ShowMySchedule_Execute()
      ' Write your code here.

    End Sub
  End Class

End Namespace

It is here that I am going to open my new screen and pass the current date as a parameter to the new screen. Here is what enter into the method.

Namespace MyFirstApplication

  Public Class CustomerList

    Private Sub ShowMySchedule_Execute()

      ' Get just the date, not the both the date and time.
      Dim curDate As DateTime = Date.Now.Date

      ' Show the screen created for the query and pass the
      ' parameter to the query via the screen.
      Me.Application.ShowEditableScheduleGrid(curDate)

    End Sub
  End Class

End Namespace

Cool, now lets hit the old F5 key and see what happens….

SCORE!! My application opened. And because the first screen has that button added to the top, the new button shows up as expected.

The button showing on the opening screen.

The button showing on the opening screen.

When I click on the button, the code fires and opens the new screen showing my filtered Schedule collection, ordered by start date. Awesome!

The new Schedule screen using the current date parameter passed to the FutureSchedule query.

The new Schedule screen using the current date parameter passed to the FutureSchedule query.

Cool! Now with a few tweaks to the screen I have an excellent scheduling system available.

Doh! I’m late for supper. I gotta go.

Cheers!

Popularity: 40% [?]

Hey, welcome back. How’s things?

…blah, blah, blah…okay, okay, enough about you already. Let’s talk about something more important. Something that will be the catalyst to bringing about world peace – table relationships in LightSwitch.

In previous LightSwitch posts I have been been able to demonstrate stuff by using one table – a Customer table. I’ve only had to manage a relatively simple set of attributes (fields) about a customer. Things like the customer name, contact name, and whether or not they flip for the bill at lunch meetings, are all very simple characteristics of a customer. One table is all I need for that kind of information.

Now that I am looking down the road though, I don’t think just one table is going to work. The overall vision for my application is such that I am going store more than just simple customer information. I am going to want to do much more; like keep track of; appointments, orders, and invoicing. I know that one customer is going have any number of appointments, orders, or invoices. I need to somehow design my data storage needs so that the data is intuitive and manageable. I am going to need more than just one table to do the job.

Relation Databases

The topic of relational database concepts is a big one, and too big for this blog post, but important to understand in creating LigthSwitch applications. If you really want to dive into the deep end of the topic pool, just Google “what is a relation database”. I think you’ll get a couple few hits on that one.

For clarity sake however, here is a condensed Cole’s notes version…

The relation database concept has been around since the 70′s, maybe even earlier. In essence, relational databases separate information into chucks of data in a way that make bits of that data unique. Relationships are created between these chucks of data so that the data is persisted as pieces of information that are relative to each other.

For example, a company has a bunch of customers. Each of those customers may have orders, and each of those orders will have details about the orders on them. Putting all that information into just one place would make managing that information very expensive and ineffective. So, rather than putting all that data into one spot, like a giant spreadsheet, relational databases separate the data into related pieces. This may mean that customer information is one place, order information is in another, and details of the orders are in their own spots.

Understanding the concept of relational databases is fundamental when it comes to defining requirements for, and creating, robust and manageable LightSwitch solutions. LightSwitch takes most, if not all, of the work out of creating and enforcing the relationships created for a database application. But before LightSwitch can do that, the design off the data and the relationships between the data must be defined by the developer using simple relational database design concepts – which ends up being mostly common sense anyway.

Really, the goal is to design so that it; makes relative sense, is easy to manage, and is inexpensive to maintain. We don’t want a design that resembles the congenital relationships between the banjo playing family members from Deliverance.  A good design with relationships that make sense will pay back big dividends in the future of any development efforts. Trust me on this. I’ve inherited a few whopper spreadsheet conversions in my day.

Creating a Relationship

So let’s get into the nitty gritty (is “nitty” that even a word?) of this LightSwitch table relationship stuff.

Using what I did in my last post, I open up my LightSwitch project and take a look at my customer table.

My Customer Table

My Customer Table

What I want to do is add some simple scheduling to my application. I want to be able to schedule when I am going to visit a customer, or maybe schedule a time when I am going to do something specific for a customer – like take them to lunch invite them to take me to lunch. I need to be able to manage schedule specific information in my application.

I figure a customer may have any number of scheduled items assigned to them. Adding all this scheduling information to my customer table is unreasonable. How can add scheduling information to the same customer table when I don’t even know how many scheduled items there will be? Considering I want to keep track of each scheduled item’s; start time, end time, and a description, it only makes sense that the scheduling should be in its own place.

I create a new table named Schedule. In my new table I create three fields (attributes) that I think will help me define my schedule item:

  • StartDateTime – a DateTime type field to store the date and time for the start of the scheduled event.
  • EndDateTime – another DateTime type field to store when the scheduled event item will end.
  • Description – a description of the scheduled event.
The new Schedule table

The new Schedule table

I’ve configured the Is Required property for each of these fields as true, because I want to ensure that I have all this information for every schedule record. I also make some edits to the Display Name property for each so that the labels on the screens I create for this entity will look nicer.

Now that I have a table to store schedule specific information, I need to somehow relate a schedule item to a customer. How easy is this? I am glad you asked. Let me show you…

On the top menu bar of the Schedule table designer I click the Relationship… item…

Click the Relationship... menu item.

Click the Relationship... menu item.

Clicking the Relationship… menu item opens the Add New Relationship window.

The Add New Relationship dialog

The Add New Relationship window

The Add New Relationship window contains a grid where the relationship can be defined. The window also displays a graphical representation of the relationship. By default, the window displays my Schedule table as the Name value in the From column. The graphical display also shows the Schedule table.

I want to create a relationship between my schedule, and the customers that the schedule items are for. So, I select my Customer table from the dropdown box in the Name row of the To column.

Selecting the Customer table in the To column

Selecting the Customer table in the To column

After selecting the Customer table for the Name value in the To column, LightSwitch defaults the remaining values for my relationship.

Defaulted relationship properties

Defaulted relationship properties

I already had a general idea of how the relationship between a schedule and a customer should be, but LightSwitch literally switched the light on in my head. The relationship designer has presented me with not only a graphical representation of the suggested relationship, LightSwitch also gives me a textual representation of the same relationship. the bottom of the window displays the rules for the relationship.

Working from the bottom up, I take a look at the textual description of the relationship:

Yes, a ‘Schedule’ must have a ‘customer’.

Yes, a ‘Customer’ can have many ‘Schedule’ instances.

A ‘Customer’ cannot be deleted, if there are related ‘Schedule’ instances? Sure, that makes sense.

Looking up at the graphical representation, it makes sense and seems to represent each line of the above.

The relationship picture

The relationship picture

I recognize the notation used in the image. It is a common data modelling technique to annotate relationships between data entities – not that you would really care, but it does make me sound like I know what I am talking about.

…hey look at that; it’s a double rainbow, OMG, Damn!

Relationship Properties

Looking back at the grid in the Add New Relationship window, I examine each of the available properties of the relationship.

Name

The Name is obvious; I want a relationship to exist from the Schedule table to the Customer table. If I had more tables to choose from, then they would also show up in the drop down lists for the name property.

Multiplicity

Multiplicity represents the constraint of whether or not one entity can have one or more instances related to the other entity. In most relational databases, there a different types of relationships that can be created.

Perhaps I wanted to have it so that a customer can only have one schedule item, and a schedule item can only have one customer. This is considered a One-to-One relationship, which probably is not a good example to use because LightSwitch does (yet?) not support One-to-One relationships. Similarly, LightSwitch does not support Many-to-Many relationships.

In my case, I want a schedule item to be related to only one customer, and that customer can have many schedule items. This is a Many-to-One relationship (many schedules to one customer).

Multiplicy in my relationship

Multiplicity in my relationship

On Delete Behavior

Most relational databases management systems (or “RDMS”) software have the ability to enforce a relationship rule that, when a record from one table is deleted, records from a related table are also deleted. In LightSwitch, this is managed by setting the On Delete Behavior property.

Currently, the on delete behavior in my relationships is set to Restricted. This means that LightSwitch will not let me delete a customer record if there are any existing schedule records. I would be forced to go in and delete each related schedule record before I could delete the customer record.

Thinking about this a bit; do I really need to worry about schedule information for a customer if I delete the customer from my application? Probably not, so I change the on delete behavior setting to “Cascade Delete”

Changing the On Delete Behavior to "Cascade delete"

Changing the On Delete Behavior to "Cascade delete"

Now the relationship is set up so that if I delete a customer record, all of that customer’s schedule records will also be deleted.

Navigation Property

If I am not mistaken, I believe the Navigation Property is simply a name that references the relationship end points. If I change the value, I see that the same gets changed in the graphical representation. Instead of changing these values, I leave them as is because the names seem to make sense being either singular or pluralized values of the table names.

So, with all that, here is my finalized relationship…

The finalized relationship

The finalized relationship

I click the OK button to save the relationship.

Back in the table designer for my Schedule table, LightSwitch now displays my new relationship, linked to my Customer table.

The relationship showing in the table designer.

The relationship showing in the table designer.

If I open the table designer for my Customer table, I also see the relationship. Pretty cool.

So now I want to start using this relationship, and start scheduling some customer meetings and visits – and start making note of who is generous in their lunches!

In my Solution Explorer I right-click the Screens folder and select Add Screen…

Add Screen...

Add Screen...

Keeping it simple, I am going to screen that will let me add and edit from a grid. So, in the Add New Screen window, I select the Editable Grid Screen template. I select Schedules from the Screen Data drop down, and then edit the Screen Name value to read CustomerScheduleGrid

Creating the CustomerScheduleGrid screen

Creating the CustomerScheduleGrid screen

Clicking OK in the Add New Screen window opens the screen designer for my new CustomerScheduleGrid screen. The only thing I am going to change here is the Display Name property for the screen. I change the display name value to Schedule so that the name of screen is nicer when is shows when the application runs.

Groovy, I a hit the F5 key to start the application in debug mode…and ah la peanut butter sandwitches…the application opens.

I click the Schedule menu item and my new CustomerSheduleGrid screen opens.

Schedule Screen

Schedule Screen

For giggles, I add a couple of schedule items. When adding the items, I see that the new relationship is enforced because the Add New Schedule window forces me to select a customer for the schedule item.

Adding a schedule record forces me to select a customer.

Adding a schedule record forces me to select a customer.

Super! I can now start managing my schedule a little better by entering some simple appointments into my application.

Well that’s enough for now. My tummy is growling. In my next post I’ll fine tune my time management processing a bit by messing with some screen designs, as well as build a query to only show what I need to see from my schedule.

Thanks for sticking around,

Cheers!


Popularity: 31% [?]

In my last post I demonstrated how to use the LightSwitch Is Computed field property. In this post I am going to extend the validation of a field by doing some Custom Validation.

The scenario is this; I want to schedule the times to go and customers. Be it for customer sales call or some training, whatever. I want to build some scheduling into my application to help better manage my time.

Here is a look at my Customer table that I created earlier:

The Customer Table

The Customer Table

I am going to do is add a new field to my Customer entity. The new field is going to be a DateTime field, rather than just a Date type. I want to keep track of the date and time that I am going to schedule.

Adding the DateTime Field to my Customer Entity

Adding the DateTime Field to my Customer Entity

Now, with my new SheduledVisitDateTime field added to my Customer entity, I am going to add it to a screen so that I can start adding some scheduling.

I already have a List and Details type screen that I created earlier. I open the CustomerList screen designer.

Over in the left had side of the designer I see the listing for the CustomersCollection that my screen is using. In the list I see my new ScheduledVisitDateTime field I created.

New field showing in screen designer

New field showing in screen designer

Because I created this screen with an earlier version of my Customer table, the new ScheduledVisitDateTime field does not automatically get added to the screen. So I drag and drop the ScheduledVisitDateTime field to the vertical stack used for the CustomerDetails section of my screen. I drop the field underneath the existing Last Contact Date field in the tree.

Adding the field to the screen (via the designer)

Adding the field to the screen (via the designer)

Super! Now I hit the F5 key to start the application in debug mode…

Hmm. Interesting. The application starts, as expected, and I can now see the ScheduledVisitDateTime field on my screen. Here is what I see…

The new field on the screen

The new field on the screen

There are three things that I see that I have to “tweak”. The first is the silly looking label. The second is that the label is bold, which suggests that the field is configured with the Is Required property set to true. The third thing I notice is the stupid looking date and time that defaults for the field.

“1/1/1900 12:00AM’ is not a date that I want to default in there. In fact, I want the field to default with nothing in it. I want the option to either have a date, or none at all. I think what happened was that because the Is Required property was set to true when I first added the field, LightSwitch may have added some default dates to all my existing records. I am not totally sure that this was the case however something in my head is telling me this is what happened.

So back to the table designer I go.

In the Customer table designer I give the ScheduledVisitDateTime field better Display Name and Description property values. I also update the Is Required property so that it isn’t checked. This will give me the option to save a customer without having a date and time value in my new field.

Updated Field Properties

Updated Field Properties

I’m pretty sure that I know a little something about setting LightSwitch field properties now, so I fire up the application again by hitting the F5 key, just to prove that little horned fella, let’s name him Nelson for now, on my shoulder wrong…

…Nelson laughs.

All looks good in the running application, except for those nasty defaults again. Not sure why those show like that. Just as a test, I added and saved a new customer, but didn’t add any value for my new field. Interestingly, the record saved with out a value, and when I view the new customer via my CustomerList screen, the new field contains an empty value.

No worries. I delete the ScheduledVistitDateTime value for all my customers – to start from a new slate.

Moving on…

With my new field, I now want to add some simple validation for any data that I enter in it. The validation, or business rule is that I want to only allow a date and time that is in the future. It would be silly to add a past date into a place where I want to store dates for the future.

“What kind of scheduling is that!?! Dumb Ass! Haw Haw” …Nelson exclaims.

Back to the Customer table designer in LightSwitch.

With the ScheduledVisitDateTime field selected, I head over to the Properties panel. At the bottom of the Properties panel is a link titled Custom Validation. I click it.

The Custom Validation link

The Custom Validation link

Clicking the Custom Validation link opens the code designer for my Customer entity. Specifically, the code designer opens with a procedure stub already created and titled ScheduledVisitDateTime_Validate()…

Private Sub ScheduledVisitDateTime_Validate(ByVal results As EntityValidationResultsBuilder)
   ' results.AddPropertyError("")

End Sub

This is where I am going to add some logic that will validate that the date and time I enter into the ScheduledVisitDateTime field are in the future. So, that’s what I do…

Private Sub ScheduledVisitDateTime_Validate(ByVal results As EntityValidationResultsBuilder)

      ' If the entered value is not in the future, then throw the error.
      If Me.ScheduledVisitDateTime < DateTime.Now() Then
        results.AddPropertyError("The scheduled date and time must be in the future.")
      End If

    End Sub

So I run the application by hitting the F5 key.

KaBLAMMO. {Insert Roger Daltrey “yeeeaaaahhhh…..” Won’t Get Fooled Again screem here}

…Nelson has fallen off my shoulder. Not sure where he went to.

Meanwhile, back at the LightSwitch ranch…the application launches and displays my CustomerList screen. I select the first customer recordI purposely click the labelled Next Scheduled Visit date and select a date in the past.

Validation errors showing on screen.

Validation errors showing on screen.

Looks like my custom validation is working! LightSwitch shows both a notification in the tab for the CustomerList screen, as well as shows a red border around my new field. Clicking on the in the message in the tab brings up the error message that I defined in my validation code…

The tab for the screen showing the error message.

The tab for the screen showing the error message.

Hovering over the tooltip corner of red border error indicator of the field causes LightSwitch to display the same error message as a tooltip…

Same error message as a ToolTip.

Same error message as a ToolTip.

Cool!

Now, I update the value to a future datetime value and presto, the error messages go away. I save the record. I now am able to better manage my time by scheduling my next visit with my customers.

In my next post, I am going to extend this scheduling stuff by adding a new table with a relationship with this one. Doing so will let me add more granular scheduling, as well as set me up to better visualize my schedule by using queries.

Stay tuned!

Popularity: 24% [?]

Here’s a little diddy about how to use the Is Computed field property in LightSwitch.

Here’s the scenario…

It takes time to build relationships with customers. Building relationships requires good communication skills. Keeping in regular contact with existing customers is what helps me generate new business, including leads to new customers. I like to keep in regular contact with my customers so that they always know I am there for them, as well as keeps my name on the front of their minds when new work comes up.

The more customers I have, the more it becomes a challenge to remember when I last contacted someone. That’s why I created a DateLastContacted field in the Customer table of my LightSwitch table. This is great at letting me see when it was I last contacted a customer. With a large list of customers, scanning a list of dates can be tedious.

What I want to do is create a simple and separate indicator to tell me that it is time to call someone. One option is to create a Query for my table and generate a screen from that. But instead, I want to simply have something show up on my screens that will put it in front of my face that I need to call the customer. To do this, I decide to create a computed field on my Customer table.

The idea is that when I open a specific screen, if the last time I contacted the selected customer was more than 30 days ago, the screen will tell me so.

So, back in the designer for my Customer table, I add a new String type field named CallThem. In the properties window for the new field, I check the Is Computed property.

New CallThem field with Is Computed checked.

New CallThem field with Is Computed checked.

Notice that setting the Is Computed property on the CallThem field displays an icon to the left of the field name in the designer. Also, setting the Is Computed property also enables the Edit Method link, immediately below the is computed property…

The now visible Edit Method link

The now visible Edit Method link

I click on the Edit Method link. LightSwitch opens up a code editing window that presents me the stub for adding code to compute the CallThem field.

Namespace MyFirstApplication

  Public Class Customer

    Private Sub CallThem_Compute(ByRef result As String)
      ' Set result to the desired field value

    End Sub
  End Class

End Namespace

This is where I am going to figure out what the value of the CallThem field should be.

What is important to understand here is how LightSwitch is working. Notice that the “result” variable into this method is passed by reference (the “ByRef”), and not by value (or “ByVal”).  This tells me that “result” is actually something that LightSwitch is managing automagically. I don’t need to worry about where that result object is, LightSwitch is taking care of it for me. Changing the result object, in this case a string type, will be persisted to wherever else the object is being used. This is great because anytime we use this computed field, the computed result is automatically used. This is an excellent example of how this model centric design works; the model being the Customer entity and anytime that model is used in the application, the computed result is available.

Now back to what I want to accomplish. I want to take a look at the date I last contacted the customer and determine how many days it’s been since I last contacted them. If it’s been more than a 30 days, I want the result to be a message to say so. If less than 30 days, then all is good and I don’t need to see anything.

I know that date I last contacted a customer is stored in a field named DateLastContacted, so I should be able to get that date and calculate how many days it has been. One problem though is to first make sure I even have a date in that DateLastContacted field. The DateLastContacted field is not a required field, so that means there could be some empty data.

Here is what I come up with…

Namespace MyFirstApplication

  Public Class Customer

    Private Sub CallThem_Compute(ByRef result As String)
      '   Create a variable and default it as an empty string.
      Dim resultString = String.Empty

      '   Is there a DateLastContacted value?
      If Not Me.DateLastContacted Is Nothing Then
        '   Calculate the number of days since the DateLastContaced.
        Dim daysSince = Date.Now.Subtract(Me.DateLastContacted).Days

        '   If the number of days is greater than 30, then set the result string variable.
        If daysSince > 30 Then
          resultString = daysSince.ToString & " Days Since Last Contact!"
        End If
      End If

      '   Set the result to use for the CallThem field.
      result = resultString
    End Sub
  End Class

End Namespace

A littled cluttered in there but I wanted to add as much commenting so that you understood what was actually happening in the code. It’s really not that complicated. With that set, anytime the CallThem field is used, the value in the field should be the result of the computed value above.

I need to now get it on a screen, but not every screen. I only want it to appear on the List and Details screen I created for my Customers. I open the CustomerList screen I had already created prior to adding the new field.

Because I am using both a list and details, the CustomerList screen designer shows me tree of stuff on the screen. I want to add the CallThem field to the right side of the screen, which happens to be called the (RIGHT COLUMN) Vertical Stack in the tree.

I select the CustomerDetails vertical stack item which enables the Add feature at the bottom of the stack. I then click Add item which then drops down to display a list of the fields in my Customer entity. In the list of fields I see the CallThem field. By default the field shows as a label because the field has been configured as a string type that is calculated.

Adding the CallThem field to the screen

Adding the CallThem field to the screen

I click the CallThem item in the list and LightSwitch adds the item to the form.

Easy enough, now lets run the application to see what happens – I pres F5 to start debugging…

Awesome! The computed value for the CallThem field is working. I select a customer who has a DateLastContacted value greater than 30 days ago, and the computed value appears in the details area of the screen…

Computed value of the CallThem field showing on a screen.

Computed value of the CallThem field showing on a screen.

Poking around the rest of the application and I notice a couple of things. The first is the label for on the screen above. The label should be named something more appropriately, or even better, not displayed at all.

I stop the application and head back to the screen designer for this screen. I select the CallThem item I added earlier. On the property window of the CallThem field I clear the display name. The display name is the label that is displayed on the form, before the actual value. This way, if the computed value is empty, nothing, not even the label will show. If the computed value contains something, then only the computed value will show – adding more of an attentive feature to my screen.

When I cleared the Dsiplay Name property of the CallThem field in the screen designer, this resulted in the item in the tree to also not show the display name…

Clearing the Display Name property

Clearing the Display Name property

I press F5 again to see what it now looks like in the application…

Groovy! The screen now only shows the computed value, or is blank if nothing is resulted from the computed value…

Only the computed value

Only the computed value

Hmmm. Checking out some of the other screens in the application I notice that still see “CallThem” showing as a label in the default edit screen (I clicked Edit in the CustomerList screen above).

I don't want the CallThem field to show anywhere else!

I don't want the CallThem field to show anywhere else!

I don’t really care if the field is even there in that screen. As mater of fact, I don’t want to see the screen anywhere else other than the screens I want it to show on.

I stop the application and fire up the table designer for my Customer table. I select the CallThem field via the designer and uncheck the Is Visible On Screen checkbox.

Set the Is Visible On Screen property to false

Set the Is Visible On Screen property to false

Oky Doky, now lets hit F5 again and see what happens…Great! It worked. No default screens, like the add or edit screens, show the CallThem field. Only my CustomerList screen shows the computed CallThem field in the details section of the screen.

Well, my lunch hour is over. Not sure what I will try tomorrow. Probably the Custom Validation feature for a field. Until then, l8r.

Cheers!

Popularity: 60% [?]

In a previous post I went through an exercise of modifying some of the properties of a table. In this post I am going to use the entity designer to customize some of the fields in my Customer entity.

Here is a look at my Customer table (entity).

Customer Entity

Customer Entity

The first field in my Customer table is a field named “Id” and it is an Int23 (Integer) type field. I notice is that the Id field is kinda grayed out a bit. This is because the field named “Id” is field that has been automatically defined as a unique identifier field for the entity. The unique id in a database table is how a record is uniquely identified. There is a lot more to it than just that however the scope of this post is to only show what I do in LightSwitch. I am planning on a future post on the whole relational database concepts and design thing, but for now, we’ll just stick with the LightSwitch stuff. Note that this field is required by LightSwitch, and as such, the Required property for this field can not be disabled.

My Customer entity was created using LightSwitch. LightSwitch automatically added the Id field. Looking at the properties of the Id field I see only two items that I can modify. The first is the Description, I enter “This is a unique id of the customer”. Nothing fantastic here.

Hey, something I just discovered! Hovering over the label for the Description property produces a tooltip that explains what the property is for…

Tooltip for the Description property

Tooltip for the Description property

Well, there you have it. This tells me that the value of the description property in tooltips or help text on the screens that display the field. Cool!

Taking a look at the Display Name property now, I hover over the label and it tells me that the display name is what shows as the label for the field when it is displayed on screens. Alright then. I change the display name value from the defaulted “Id” to “Customer ID”.

The last property is the Is Visible On Screen property. Thinking about it a bit more I wonder if there is any real value to having this field actually show up on a screen. Maybe I want open up some screen real estate by not showing this field. So, I uncheck the propery.

Looking some more at the properties window I notice a small circular button beside the text fields. Wondering what they are for, I click the button beside the description value.

What does that little circle do?

What does that little circle do?

Interesting. Seems that I can optionally select to reset the field value to what LightSwitch had originally created. Sure, why not. Let’s reset to the default value. I am not going to display the Id field anyway, so whey worry about having a tooltip anyway. I click the Reset To Default item and presto, the description property value returns to the default value (which happens to be blank for the Id field).

More on that little circle button. I am assuming that this button is used to present a context menu specifically for the field.  So far the only menu item that I can see is the Reset to Default item. Maybe other types of field properties present different types of menu items, I don’t know yet. So far, reseting to default is the only one I have experienced so far.

Moving on to my next field, the CustomerName field. I added this field to store information about the name of my customer. It is a string data type, which really means you can have just about anything for text in there, including just numbers if you want.

Clicking on the CustomerName value within the table designer allows me to edit the name property, directly within the designer. Similarly, I can change the field type and the required properties from within the designer. Each of these three properties are also available to edit in the Properties window, so I am going to work directly from there for now.

Making the CustomerName field the active field in the designer caused my Properties window to change to show the properties that are available for the field. Because the field is a String type of field, the properties windows includes properties that are available to String type fields.

The first property is the Is Computed property. If enabled, I can add a business rule that would compute the value of my field. A good example of this may be to show a money value that has to have some tax applied. I am thinking that I am going to tackle this subject in my next post. For now, I am going to leave this unchecked.

The IsSearchable property, if checked, will allow this field to be searchable when doing searches from the default search screens. If I end up with a few hundred customers in my application, you can bet that I am going to want do some searching based on their name. I leave this property as checked. (Make sure your table is searchable too, otherwise this field property is useless if can’t search the table to begin with).

I leave the Name property as is.

The ChoiceList link on the properties window allows me to create a list of possible choices for my field. I am going to leave this alone for now.

For the Description property, I enter “This is the name of the customer” .

Next I change the Display Name property to “Name” so that labels and column headers of my default screens shows this.

I do want this name displayed on the default screens, so I make sure the Is Visible On Screen is checked.

The Validation section contains properties where I can apply some simple rules about the field. The customer name is required for my application, so I make sure the Is Required property is checked.

I can also define the maximum number of characters allowed in my text field by entering a number into the Maximum Length property. Note that you can only enter a valid number (between 1 and 2147483647) (Although for some reason it allows 0 (zero) to be entered. I’ve changed the customer name field maximum length property from the default 255 to just 50.

The Custom Validation link allows me to enter some…custom validation or business rule via code. I’m not going to do any custom validation just yet. I’ll touch on this one in another post too.

Here is what my CustomerName field properties look like…

CustomerName field properties window

CustomerName field properties window

For the remaining fields, I update each so that they are NOT required, except for my IsActive field as I need to know if the customer is still an active account or not. The customer name I also want to make sure has information in it I create or edit a customer.

Back to the CustomerType field. Although the field is a String  type field, I want to constrain the information to only a specific set of values. This is valuable in scenarios where I want to search my customers. There may be a customer type that I applied to many customers, but formed or spelled the information differently. There would be risk that I would miss some customers when searching for a specific type of  customer. By constraining the information allowed in the field to a defined list, I make sure that the customer type values are consistent for all customers.

As an alternative to selecting the CustomeType field by clicking on it in the designer, I  select it from the dropdown at the top of the properties window.

Field selected=

Next, I hover over the Choice List to see what is tells me.

Tooltip for Choice List link

Tooltip for Choice List link

Clicking on the Choice List link opens up the Choice List dialog. The choice list contains two columns. The first column is the Value column. The value column is what will be used as your field value when the choice is selected. The second column is the Display Name which is what will be displayed in the choice list that shows up on screens. If nothing is entered into the Display Name column, the Display Name defaults to the value entered into the Value column.

I enter some choices that I want to have available for my CustomerType field…

Some Choice List values

Some Choice List values

I click on the OK button and head back to the properties window. On the properties window I now see a red X icon beside the Choice List link. Hovering over the icon I see this…

Choice List option to delete

Choice List option to delete

It seems that I can now delete the choice list that I created. I don’t want to delete it. I clicked on the Choice List link to see if I could later edit the list I created, and it opened with my list.

To see how this works on a screen, I click the Start Debugging button. In my NewCustomer screen, the CustomerType field is enabled with a dropdown box that offers a items from the choice list I created.

Choice List in a screen

Choice List in a screen

I also have the option of still being able to manually enter anything I wanted, so I am not constrained to only the items in the list. This is great because not only do I have an easy to reference list of common customer types to use, I still have the flexibility to add something that is not on the list…

In the screen I happen to notice that the labels beside my fields are quite what I want. So, I stop the application and head back to the properties of each field to update the Display Name value of each property. And viola…

New display names for my fields.

New display names for my fields.

As far as experiencing how to use the designer to modify the properties of a field, that is it in a nutshell. There are other types of fields that other properties that can be managed too. These include:

  • Date, DateTime, and Double type fields have properties to define the minimum and maximum values that are allowed.
  • A Decimal field type has minimum and maximum value properties, as well as properties to define the values precision and scale.
  • The EmailAddress type, a custom business entity type, has a property to require that an email domain in its value.
  • Money entity types that have a number of properties to define the appearance of the value, such as the currency symbol and number of decimal spaces. Similar to the Decimal field, the money type has validation properties for the minimum, maximum, and precision and scale of the value.

As I move forward in creating other tables in my project, I’ll likely come across something else that might be unique to the field type. Until them, I think I now have a pretty good understanding of how to manage the fields of my entities using the LightSwitch designers.

In my next post I am going to create a couple of more tables and then apply relationships to those tables.

Cheers!

Popularity: 39% [?]