ComboBox
in namespace DotVVM.BusinessPack.Controls
Renders a ComboBox control similar to HTML <select> element.
Usage & Scenarios
This control is different from the built-in ComboBox and is not derived from it.
The Business Pack ComboBox control is a text field which suggests items to select. It can perform server search, use custom templates for the suggested items and let the user to add his own values which are not present in the DataSource collection.
The Business Pack includes a similar control called DropDownList which is not a text field and cannot be typed into, however the user can also select items from a list which appears after clicking into the control.
If you need to select multiple values, you can use the MultiSelect.
Sample 1: Basic Usage
The DataSource property specifies a collection of strings. For each item in the collection, a list item is created.
The SelectedValue property is bound to a property which contains the item from the DataSource collection which was selected in the control. The data-binding works in both ways, so you can either read, or modify the property in the viewmodel and the control will get synchronized to reflect the changes.
<bp:ComboBox DataSource="{value: Countries}"
SelectedValue="{value: SelectedCountry}"
Placeholder="Please select Country" />
<p>Selected Country: {{value: SelectedCountry}}</p>
using System.Collections.Generic;
using DotVVM.Framework.ViewModel;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample1
{
public class ViewModel : DotvvmViewModelBase
{
public string SelectedCountry { get; set; }
public List<string> Countries { get; set; } = new List<string> {
"Czech Republic", "Slovakia", "United States"
};
}
}
Sample 2: Working with Objects
When the DataSource collection is bound to a collection of objects, you may use the ItemTextBinding to specify, which property of the object in the collection will be displayed as a text of a particular list item.
The SelectedValue will still contain the object from the DataSource collection which is selected.
In order to allow the control to uniquely identify these objects, you need to use the ItemKeyBinding property to define a property which can work as a key. The key must be unique for all items in the collection, otherwise the control will not work properly.
The Placeholder property specifies the text which is displayed when no value is selected.
<bp:ComboBox DataSource="{value: Countries}"
SelectedValue="{value: SelectedCountry}"
ItemTextBinding="{value: Name}"
ItemKeyBinding="{value: Id}"
Placeholder="Please select Country" />
<p>Selected Country: {{value: SelectedCountry.Name}}</p>
using System.Collections.Generic;
using DotVVM.Framework.ViewModel;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample2
{
public class ViewModel : DotvvmViewModelBase
{
public Country SelectedCountry { get; set; }
public List<Country> Countries { get; set; } = new List<Country> {
new Country { Id = 1, Name = "Czech Republic" },
new Country { Id = 2, Name = "Slovakia" },
new Country { Id = 3, Name = "United States" }
};
}
}
using System.Collections.Generic;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample2
{
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Cities { get; set; } = new List<string>();
public bool IsEnabled { get; set; } = true;
public bool IsChecked { get; set; }
}
}
Sample 3: Working with Objects 2
To make the SelectedValue property contain only a value of a specific property from the DataSource object (like the Id property of the selected object), you may use the ItemValueBinding property.
The SelectedValue property will then contain only the value of the property specified in the ItemValueBinding. Provided the values of the properties used as a value are unique, you don't need to specify the ItemKeyBinding property.
The
ItemKeyBindingproperty is required only when the control cannot compare the objects in theDataSourcecollection with the object in theSelectedValueproperty. If theItemValueBindingis set and makes theSelectedValueproperty use a primitive type that can be compared, theItemKeyBindingproperty is not needed. Similarly, if theDataSourcecollection contains only primitive values (string,intetc.), theItemKeyBindingproperty is not necessary.
<bp:ComboBox DataSource="{value: Countries}"
SelectedValue="{value: SelectedCountryId}"
ItemTextBinding="{value: Name}"
ItemValueBinding="{value: Id}"
Placeholder="Please select Country" />
<p>Selected Country ID: {{value: SelectedCountryId}}</p>
using System.Collections.Generic;
using DotVVM.Framework.ViewModel;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample3
{
public class ViewModel : DotvvmViewModelBase
{
public int? SelectedCountryId { get; set; }
public List<Country> Countries { get; set; } = new List<Country> {
new Country { Id = 1, Name = "Czech Republic" },
new Country { Id = 2, Name = "Slovakia" },
new Country { Id = 3, Name = "United States" }
};
}
}
using System.Collections.Generic;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample3
{
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Cities { get; set; } = new List<string>();
public bool IsEnabled { get; set; } = true;
public bool IsChecked { get; set; }
}
}
Sample 4: Item Templates
To display custom content in the list items, you can use the ItemTemplate property to declare a custom template for the list items.
<bp:ComboBox DataSource="{value: Countries}"
SelectedValue="{value: SelectedCountryId}"
ItemValueBinding="{value: Id}"
ItemTextBinding="{value: Name}"
Placeholder="Please select Country">
<ItemTemplate>
<span>{{value: Id}}. {{value: Name}}</span>
</ItemTemplate>
</bp:ComboBox>
using System.Collections.Generic;
using DotVVM.Framework.ViewModel;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample4
{
public class ViewModel : DotvvmViewModelBase
{
public int? SelectedCountryId { get; set; }
public List<Country> Countries { get; set; } = new List<Country> {
new Country { Id = 1, Name = "Czech Republic" },
new Country { Id = 2, Name = "Slovakia" },
new Country { Id = 3, Name = "United States" }
};
}
}
using System.Collections.Generic;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample4
{
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Cities { get; set; } = new List<string>();
public bool IsEnabled { get; set; } = true;
public bool IsChecked { get; set; }
}
}
Sample 5: Changed Event
The Changed event specifies the command in the viewmodel that is triggered whenever the user changes the value in the control.
<bp:ComboBox DataSource="{value: Countries}"
SelectedValue="{value: SelectedCountry}"
ItemTextBinding="{value: Name}"
ItemKeyBinding="{value: Id}"
Placeholder="Please select Country"
Changed="{command: CountryChanged()}" />
<bp:ComboBox DataSource="{value: Cities}"
SelectedValue="{value: SelectedCity}"
Placeholder="Please select City" />
<p>You've selected: {{value: SelectedCity}}, {{value: SelectedCountry.Name}}</p>
using System.Collections.Generic;
using DotVVM.Framework.ViewModel;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample5
{
public class ViewModel : DotvvmViewModelBase
{
public Country SelectedCountry { get; set; }
public string SelectedCity { get; set; }
public List<Country> Countries { get; set; } = new List<Country> {
new Country { Id = 1, Name = "Czech Republic", Cities = new List<string> { "Praha", "Brno" } },
new Country { Id = 2, Name = "Slovakia", Cities = new List<string> { "Bratislava", "Košice" } },
new Country { Id = 3, Name = "United States", Cities = new List<string> { "Washington", "New York" } }
};
public List<string> Cities { get; set; } = new List<string>();
public void CountryChanged()
{
SelectedCity = null;
Cities = SelectedCountry?.Cities ?? new List<string>();
}
}
}
using System.Collections.Generic;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample5
{
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Cities { get; set; } = new List<string>();
public bool IsEnabled { get; set; } = true;
public bool IsChecked { get; set; }
}
}
Sample 6: New Items
To allow entering a custom value which is not present in the DataSource collection, you can use the AllowNewItems property.
The Text property contains the exact value the user entered in the text field.
This feature can be used only when the DataSource collection contains string values.
<bp:ComboBox DataSource="{value: Countries}"
Text="{value: TypedCountry}"
SelectedValue="{value: SelectedCountry}"
AllowNewItems="true"
Placeholder="Please select or type Country" />
<p>Selected Country: {{value: SelectedCountry ?? TypedCountry}}</p>
using System.Collections.Generic;
using DotVVM.Framework.ViewModel;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample6
{
public class ViewModel : DotvvmViewModelBase
{
public string SelectedCountry { get; set; }
public string TypedCountry { get; set; }
public List<string> Countries { get; set; } = new List<string> {
"Czech Republic", "Slovakia", "United States"
};
}
}
Sample 7: Server Search
The LoadItems property can specify a command in the viewmodel which will return new items based on what the user types in the control.
Typically, this method is used with the Static Command and the method should return a list of items,
and the value of methods text parameter is based on the text user typed into the search field.
The method in the viewmodel performs the search and returns a collection of items. These items are either added to existing items in the DataSource collection or they replace the existing items. It depends on the LoadItemsMode property.
If you use the static command, don't forget to decorate the method with the AllowStaticCommand attribute.
In the future versions of DotVVM, there are plans to enhance the server search functionality with more features (e.g. REST API integration).
<bp:ComboBox DataSource="{value: Countries}"
SelectedValue="{value: SelectedCountry}"
ItemTextBinding="{value: Name}"
ItemKeyBinding="{value: Name}"
LoadItems="{staticCommand: LoadCountries(text)}"
Placeholder="Please select Country" />
<p>Selected Country: {{value: SelectedCountry.Name}}</p>
using System.Collections;
using System.Collections.Generic;
using DotVVM.Framework.ViewModel;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample7
{
public class ViewModel : DotvvmViewModelBase
{
public Country SelectedCountry { get; set; }
public List<Country> Countries { get; set; } = new List<Country>();
[AllowStaticCommand]
public IEnumerable<Country> LoadCountries(string text)
{
yield return new Country
{
Name = text
};
}
}
}
using System.Collections.Generic;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample7
{
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Cities { get; set; } = new List<string>();
public bool IsEnabled { get; set; } = true;
public bool IsChecked { get; set; }
}
}
Sample 8: Item Keys
The ItemKeyBinding property must be used when the SelectedValue is not a primitive type (like string, int etc.).
This property helps the control to uniquely identify the selected object.
<bp:ComboBox DataSource="{value: Cities}"
SelectedValue="{value: SelectedCity}"
ItemTextBinding="{value: Name}"
ItemKeyBinding="{value: Id}"
Placeholder="Select city">
<ItemTemplate>
<span>{{value: Name}}, {{value: Country}}</span>
</ItemTemplate>
</bp:ComboBox>
<p>Selected City: {{value: SelectedCity.Name}}, {{value: SelectedCity.Country}}</p>
using System.Collections.Generic;
using DotVVM.Framework.ViewModel;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample8
{
public class ViewModel : DotvvmViewModelBase
{
public List<City> Cities { get; set; } = new List<City> {
new City { Id = 1, Name = "Praha", Country = "Czech Republic" },
new City { Id = 2, Name = "Bratislava", Country = "Slovakia" },
new City { Id = 3, Name = "Austin", Country = "Texas" }
};
public City SelectedCity { get; set; }
}
}
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample8
{
public class City
{
public int Id { get; set; }
public string Name { get; set; }
public string Country { get; set; }
}
}
Sample 9: Customizing Icons
The icons used by the control can be customized using the following inner elements:
ToggleIconrepresents an icon that opens the popup with list of available items. The default isChevronDownicon.UnselectIconrepresents an icon that allows the user to deselect the item. The default isCloseicon.
See the Icon documentation to find about using other icon packs.
<bp:ComboBox DataSource="{value: Countries}"
SelectedValue="{value: SelectedCountry}"
Placeholder="Please select Country" >
<ToggleIcon>
<bp:Icon Icon="ChevronDown"></bp:Icon>
</ToggleIcon>
<UnselectIcon>
<bp:Icon Icon="Close"></bp:Icon>
</UnselectIcon>
</bp:ComboBox>
using System.Collections.Generic;
using DotVVM.BusinessPack.Controls;
using DotVVM.Framework.ViewModel;
namespace DotvvmWeb.Views.Docs.Controls.businesspack.ComboBox.sample9
{
public class ViewModel : DotvvmViewModelBase
{
public string SelectedCountry { get; set; }
public List<string> Countries { get; set; } = new List<string> {
"Czech Republic", "Slovakia", "United States"
};
}
}
Properties
| Name | Type | Description | Notes | Default Value | |
|---|---|---|---|---|---|
| AllowNewItems | Boolean | Gets or sets whether it is allowed to create new items from the entered text. |
attribute
static value
bindable
|
False | |
| AllowUnselect | Boolean | Gets or sets whether the selected value can be unselected. The default value is true. |
attribute
static value
bindable
|
True | |
| AutoFocus | Boolean | Gets or sets whether the control should have focus when page loads or when a dialog is opened. The default value is false. |
attribute
static value
|
False | |
| ClientIDMode | ClientIDMode | Gets or sets the client ID generation algorithm. |
attribute
static value
|
Static | |
| DataContext | Object | Gets or sets a data context for the control and its children. All value and command bindings are evaluated in context of this value. The DataContext is null in client-side templates. |
attribute
bindable
|
null | |
| DataSource | IEnumerable | Gets or sets the data source containing data for this control. |
attribute
bindable
|
null | |
| Enabled | Boolean | Gets or sets whether the control is enabled and can be modified. |
attribute
static value
bindable
|
True | |
| ID | String | Gets or sets the control client ID within its naming container. |
attribute
static value
bindable
|
null | |
| IncludeInPage | Boolean | Gets or sets whether the control is included in the DOM of the page. |
attribute
bindable
|
True | |
| InnerText | String | Gets or sets the inner text of the HTML element. Note that this property can only be used on HtmlGenericControl directly and when the control does not have any children. |
attribute
static value
bindable
|
null | |
| ItemEnabledBinding | IValueBinding<Boolean?> | Gets or sets the binding indicating whether a data item can be selected. |
attribute
bindable
|
null | |
| ItemKeyBinding | IValueBinding | Gets or sets the binding which retrieves the unique key of a data item. |
attribute
bindable
|
null | |
| ItemTemplate | ITemplate | Gets or sets the template used to render each data item. |
inner element
static value
default
|
null | |
| ItemTextBinding | IValueBinding<String> | Gets or sets the binding which retrieves the text from a data item. It retrieves the whole item by default. |
attribute
bindable
|
null | |
| ItemValueBinding | IValueBinding | Gets or sets the binding which retrieves a value from a data item. It retrieves the whole item by default. |
attribute
bindable
|
null | |
| LoadItems | ComboBox+LoadItemsFunc | Gets or sets a function used to load additional items from server. For example, it is used to search for items on server-side. |
attribute
bindable
|
null | |
| LoadItemsMode | LoadItemsMode | Gets or sets how are items returned by the LoadItems command. They can either be merged with existing items in the data source; or they can replace them. The default value is Merge. |
attribute
static value
bindable
|
Merge | |
| Placeholder | String | Gets or sets the text displayed when no item is selected (or when text is empty). |
attribute
static value
bindable
|
null | |
| SelectedValue | Object | Gets or sets the value of the item selected by user. |
attribute
bindable
|
null | |
| TabIndex | Int32 | Gets or sets the order in which the control is reachable in sequential keyboard navigation. The default value is 0 which means the document order. |
attribute
static value
bindable
|
0 | |
| Text | String | Gets or sets the text value of the control (useful for searching or creating new items). |
attribute
bindable
|
||
| ToggleIcon | IconBase | Gets or sets the icon displayed on the toggle button. |
inner element
static value
bindable
|
null | |
| UnselectIcon | IconBase | Gets or sets the icon displayed on the unselect button. |
inner element
static value
bindable
|
null | |
| Visible | Boolean | Gets or sets whether the control is visible. When set to false, `style="display: none"` will be added to this control. |
attribute
bindable
|
True |
Events
| Name | Type | Description | |
|---|---|---|---|
| Changed | Command | Gets or sets the command triggered when the text (or value) is changed. |