LightSwitch – Limiting Item Selections using a ComboBox

Overview of Article

One of the annoyances about the LightSwitch AutoCompleteBox is that there isn’t an option to limit selections to only those items which are shown in the list. Non existent values can be typed in, causing validation errors to occur when a screen is saved.

image

Fig 1 – Illustration of AutoCompleteBox failing to limit selections.

Fortunately, the Silverlight ComboBox control can limit items to the list and the following article describes how we can use this control on a LightSwitch screen.

In the following example, we’ll create a customer entry screen and allow the user to select from a list of available Countries.

 

Data

The example solution contains a Person table and a Country table. The table schemas and relationships are illustrated in the following images below.

image
Fig 2 – Illustration of Person table

image
Fig 3 – Illustration of Country table

image

Fig 4 – One to Many relationship between Country and Person 

 

Screens

The following section describes the creation of the screens in the project..

  1. First of all, create an ‘Editable Grid Screen’ on the Country table to enable some Countries to be added.
  2. Create a ‘New Data Screen’ on the Person table.
  3. By default, an ‘AutoCompleteBox’ is created on the Country field. Change this to ‘Custom Control’ using the drop down list to the left of the control. After doing so, bring up the properties of the control and click on the ‘Change…’ link next to the ‘Custom Control’ field. In the dialog that appears, select the ‘ComboBox’ control from within the System.Windows.Controls namespace.

    image  image
    Fig 5 – Changing the AutoCompleteBox to a ComboBox

  4. We now need to create a data source in order to populate our ComboBox with a list of available Countries. In order to do this, click on the ‘Add Data Item’ button, select the ‘Query’ radio button and select ‘Countries – Country (All)’. Retain the default name of ‘Countries’.

    image
    Fig 6 – Creating a data source for our ComboBox
     

  5. We now need to write some code to bind our ComboBox to the person entity. Click on ‘Write Code’ button and select the ‘_Activated’ event. Now write the following code:
  6. Private Sub CreateNewPerson_Activated()
        Dim comboControl As IContentItemProxy = Me.FindControl("Country")
        comboControl.SetBinding(System.Windows.Controls.ComboBox.ItemsSourceProperty, "Screen.Countries", Windows.Data.BindingMode.TwoWay)
        comboControl.SetBinding(System.Windows.Controls.ComboBox.SelectedItemProperty, "Screen.PersonProperty.Country", Windows.Data.BindingMode.TwoWay)
    End Sub
    

    Here’s the C# equivalent…

    private void CreateNewPerson_Activated()
    {
        IContentItemProxy comboControl = this.FindControl("Country");
        comboControl.SetBinding(System.Windows.Controls.ComboBox.ItemsSourceProperty, "Screen.Countries", System.Windows.Data.BindingMode.TwoWay);
        comboControl.SetBinding(System.Windows.Controls.ComboBox.SelectedItemProperty, "Screen.PersonProperty.Country", System.Windows.Data.BindingMode.TwoWay);
    }
    
  7. Now run our application and open the ‘Create Person’ screen. The list of Countries is now limited to those shown in the list.
    image
    Fig 7 – Illustration of final screen showing the ComboBox which can not be typed into.

Conclusion 

This article demonstrates how we can limit drop down choices by using a Silverlight ComboBox. It also illustrates the data binding syntax which is used when binding custom controls. The image below illustrates the relationship between the designer and the call to the SetBinding method. This is particularly relevant when creating a ‘details screen’ as the default entity will be ‘Person’ rather than ‘PersonProperty’.

  

image

Fig 8 – Illustration of DataBinding Code

 

About dotnettim

Tim Leung is a Microsoft .Net / SQL Server developer based in England.
This entry was posted in LightSwitch. Bookmark the permalink.

22 Responses to LightSwitch – Limiting Item Selections using a ComboBox

  1. Yann says:

    Hi Tim,

    Does this still give you the ability to type & have matches displayed, like AutoCompleteBox? Or does this go back to the original ComboBox behavior?

    Yann

  2. dotnettim says:

    Hi Yann,

    This goes back to the orginal ComboBox behaviour.

    If the focus is set to the control and you type into it, nothing happens.

    (ie) It doesn’t even bring up the first record that begins with the letter that you’ve typed in which is the type of behaviour that you get in an ‘HTML ‘ type dropdown.

    The only keyboard keys that will do anything are the up and down arrow keys.

    Tim

  3. Excellent article Tim! Thanks so much.

    We’re looking forward to seeing more.

    Cheers!

  4. Pingback: Microsoft Lightswitch select entity property name in combobox « Tejana

  5. Ano says:

    Hi Tim,
    Very useful article.
    2 questions about default value :
    – How can we set a default value (for example Spain) ?
    – Can the default value be the most used value in the table ?
    Thanks in advance
    Ano

  6. dotnettim says:

    Hi Ano,

    Thanks for your comment! I don’t exactly have an answer for you because I think there may be a bug when the above databinding syntax is used on a ‘New Data Entry’ screen.

    In theory however, the recommended way to set default values is at the entity level.

    If you want to set the default value Country of all people to ‘Spain’, open the ‘Person’ table in the designer, click on the ‘Write Code’ button and select ‘Person_Created’ event. You can now write code along the following lines to set the default country to Spain.

    Private Sub Person_Created()
    Me.Country = DataWorkspace.ApplicationData.Countries.Where(Function(a) a.CountryName = “Spain”).FirstOrDefault
    End Sub

    The above ‘where’ clause could be adapted to return the most used value in the table.

    I’ll hopefully find an answer to this soon.

    Tim

    • Ano says:

      Hi Tim,

      Thanks for your help.
      I’m new in programming with vb.net and I don’t know why and how use this or that. Could you give me some advice to improve my skills (books, web site, etc) ?
      Thanks in advance.
      Ano

  7. Adrian says:

    Excelent article! Please, I have one question, I am working on a very tight time project and need to have a way to customize the modal edit window that pops up when adding a new record, to add on of the comboboxes in the article above. Would you, please know a way of doing this?

    thank you,
    Adrian

  8. dotnettim says:

    Thanks for your comment Adrian!

    Just to clarify the question for others, this question relates to the type of auto-generated screen that appears when the ‘+’ or ‘Edit’ buttons are clicked at the top of LightSwitch grids.

    Unfortunately, it’s not easy to modify these screens. However, the following thread describes a method to do this.

    http://social.msdn.microsoft.com/Forums/en-US/lightswitchgeneral/thread/f12008d5-cc2d-4c10-af9a-2900534a45ba

    The VB.Net version of this code can be found here.

    http://social.msdn.microsoft.com/Forums/en-US/lightswitchgeneral/thread/35b0e258-e0c0-4edb-9c6d-2d94864ef0f9

    Hopefully, this will be of some use to you.

    Tim

  9. venu says:

    I Want to change the width of the combobox
    how to do that..
    pls..help..me

  10. dotnettim says:

    Hi Venu, you can set the dimensions of the ComboBox using the sizing options. If you go to
    the properties of the ComboBox, there’s a sizing group that allows you
    specify a width in pixels or a maximum size.
    Tim

  11. mitkodi says:

    If I add to a screen a Local Property data item and define a Choice List for it, how can I bind ComboBox.ItemsSource to this list of values?
    Thanks!

    • dotnettim says:

      Hi mitkodi,
      If you’re using a choice list, this technique cannot be used.
      There isn’t any easy way to programmatically retrieve the items in a choice list so the best bet is to place these ‘choice’ items in a separate table rather than use a choice list.
      Tim

  12. How can I apply this if I have a grid of items instead of a single item in the screen? I have tried something like this but it fails telling me that SetBinding does not work for controls inside a collection:

    partial void MyCollection_SelectionChanged()
    {
    var selected = this.MyItems.SelectedItem;
    var comboControl = this.FindControlInCollection(“TheSelectableProperty”, selected);
    comboControl.SetBinding(ItemsSourceProperty, “Screen.SelectableItems”, BindingMode.TwoWay);
    comboControl.SetBinding(System.Windows.Controls.ComboBox.SelectedItemProperty, “Screen.TheCurrentItem.SelectableProperty”, BindingMode.TwoWay);
    }

  13. Tihomir says:

    This is my first touch on lightswitch and I decided set this blog as start point to go. I have a problem tryng to put combo in rfitable grid, because every row get same value from combo.

  14. Russell Eubanks says:

    I appreciate your article and have found your book Pro Visual Studio LightSwitch 2011 Development (with Yann Duran) to be just excellent. However, when I tried your technique for using a ComboBox control I found that the contents of the control were not initialized when I selected an entity instance, and when I selected a choice from the ComboBox control, that choice remained on the screen for every entity instance selected. My code:

    partial void MaintainHouseholds_Activated()
    {
    IContentItemProxy maritalStatusControl = this.FindControl(“MaritalStatus1”);
    maritalStatusControl.SetBinding(System.Windows.Controls.ComboBox.ItemsSourceProperty,
    “Screen.MaritalStatuses”,
    System.Windows.Data.BindingMode.TwoWay);
    maritalStatusControl.SetBinding(System.Windows.Controls.ComboBox.SelectedItemProperty,
    “Screen.HouseholdMembersInHousehold.SelectedItem.MaritalStatus”,
    System.Windows.Data.BindingMode.TwoWay);
    }

    Did I miss something?

    • dotnettim says:

      Hi Russel, Thanks a lot for your comment 🙂

      As you’ve probably discovered, there are a couple of issues with this technique.

      I’d really like for Microsoft to natively build this functionality into the AutoCompleteBox. I’ve added a suggestion on Microsoft Connect, but I think it’s unlikely that they’ll do this soon.

      Just to confirm, are you using this code on a new or details type screen? A limitation of this technique is that it doesn’t work on grid or list type screens, and exhibits the behaviour that you’ve described.

      The code you’ve posted looks ok. The contents of the control can be very slow to load at first (which gives the impression that it’s not initializing).

      Alternatively, another way of limiting item selections in an AutoCompleteBox is to use a choice list, rather than a related MaritalStatus table. But I realise that this isn’t ideal, particularly if you need to store marital status in several tables.

      Tim

  15. Russell Eubanks says:

    Now that I’ve installed Visual Studio 2012 I revisited this issue to see if MS had addressed the problems with using a ComboBox control. I’m still getting the effect that the existing value of the property is not loaded into the field, and when I select a value from the list, that value persists in the field even when a new entity is displayed having a different value. Is there any way to specify an Auto Complete Box for a field if there’s not a relationship specified between the entity and the table data of values for that field?

  16. Edward Piccoli says:

    Hi and thanks for the nice info. I tried putting the ComboBox in an Editable Grid. When I run the program, the ComboBox appears OK but no country data shows. I did a debug and it runs through the “EdiableGrid_Activate” OK but no data shows. Do I need to change the code you show. Still green on coding? Thanks

  17. You are so fantastic!!! I’ve become obsessed with your blog and I spend most of my days reading all your archives. And I made a blog account JUST to post comments. I wish I had found you sooner, and I wish you updated as much as you did in the past! You must be constantly busy now though because you’re so famous!
    !

  18. harshdeep88 says:

    Hi Tim,

    Really it is a nice article. But I want to know one more thing that can we map combo box with choice list of a column?

Leave a reply to dotnettim Cancel reply