Multiple Selection in ComboBoxEdit, LookUpEdit, and ListBoxEdit
- 5 minutes to read
Initially, ComboBoxEdit, LookUpEdit, and ListBoxEdit editors use single selection.
To enable multiple selection in these editors, you need to change their operation mode. To do this, initialize an editor’s StyleSettings property with a corresponding setting object:
<dxe:ComboBoxEdit ...>
<dxe:ComboBoxEdit.StyleSettings>
<dxe:CheckedComboBoxStyleSettings/>
</dxe:ComboBoxEdit.StyleSettings>
</dxe:ComboBoxEdit>
Refer to the following help topics to learn more about available operation modes:
When you define these editors in In-Place mode, you use the ComboBoxEditSettings, LookUpEditSettings, and ListBoxEditSettings objects. These objects have the StyleSettings property as well:
<dxg:GridColumn ...>
<dxg:GridColumn.EditSettings>
<dxe:ComboBoxEditSettings ...>
<dxe:ComboBoxEditSettings.StyleSettings>
<dxe:CheckedComboBoxStyleSettings/>
</dxe:ComboBoxEditSettings.StyleSettings>
</dxe:ComboBoxEditSettings>
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
In ListBoxEdit
and ListBoxEditSettings
, set the SelectionMode property to Multiple or Extended to enable multiple selection.
Bind to Data
An editor with multiple selection enabled uses values of the List<Object>
data type in its EditValue property. When you select items in your editor, it creates a new List<Object>
instance that contains the selected values. The values to store in this list depend on whether or not you specify the ValueMember
property.
The following example shows a ViewModel used to implement multi-selection in editors. This ViewModel contains the following Item
class, the Items
collection property (used in your editor’s ItemsSource
property), and the SelectedItems
property (used in the EditValue
property):
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
}
//...
public ObservableCollection<Item> Items { get; set; }
= new ObservableCollection<Item>(Enumerable.Range(0, 10)
.Select(c => new Item
{
Id = c,
Name = "Item #" + c
}));
public List<Object> SelectedValues { get; set; }
If you use a ViewModel similar to the one shown above and leave an editor’s ValueMember property undefined, the EditValue
and SelectedValues
properties will contain List<Object>
with the Item
objects selected from Items
. Note that in the following example, an editor’s ValueMember property is not set:
<dxe:ListBoxEdit ItemsSource="{Binding Items}"
EditValue="{Binding SelectedValues}"
DisplayMember="Name">
<dxe:ListBoxEdit.StyleSettings>
<dxe:CheckedListBoxEditStyleSettings/>
</dxe:ListBoxEdit.StyleSettings>
</dxe:ListBoxEdit>
If you use a ViewModel similar to the one shown above and set an editor’s ValueMember property, the EditValue
and SelectedValues
properties will contain List<Object>
with the Id
property values of the Item
objects selected from ItemsSource
:
<dxe:ListBoxEdit ItemsSource="{Binding Items}"
EditValue="{Binding SelectedValues}"
ValueMember="Id"
DisplayMember="Name">
<dxe:ListBoxEdit.StyleSettings>
<dxe:CheckedListBoxEditStyleSettings/>
</dxe:ListBoxEdit.StyleSettings>
</dxe:ListBoxEdit>
If you add or remove values to/from EditValue’s List<Object>
instance, the editor does not select/unselect corresponding items. Instead, create a new List<Object>
instance with the required set of values and use it in EditValue.
When you do not define ValueMember
and use complex objects in ItemsSource, EditValue’s List<Object>
contains the editor’s ItemsSource
values. In the example above, if you want to set SelectedValues
in code, set it to List<Object>
with Item
instances from the Items
collection. (Otherwise, the editor does not determine which objects from the source it should select.)
SelectedValues = new List<object>() { Items[0], Items[2], Items[4] };
How to Use Editors with Multi-Selection in GridControl Cells
To specify an in-place editor for a GridColumn, use the techniques described in the following help topic: In-place Editors. The editor’s EditValue is associated with the data item property that you define in the GridColumn. For more information, refer to the following help topic: Binding Columns to Data Source Fields.
When you enable multiple selection in an editor, it uses List<Object>
in its EditValue. However, FieldName does not support the editing of collection properties. So, you are not able to edit the SelectedValues
property in the GridColumn cells shown in the following example:
public class GridDataItem {
//...
public List<Object> SelectedValues { get; set; }
//...
}
<dxg:GridColumn FieldName="SelectedValues" ...>
<dxg:GridColumn.EditSettings>
<dxe:ComboBoxEditSettings ...>
<dxe:ComboBoxEditSettings.StyleSettings>
<dxe:CheckedComboBoxStyleSettings/>
</dxe:ComboBoxEditSettings.StyleSettings>
</dxe:ComboBoxEditSettings>
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
Do one of the following to enable editing in this scenario:
Use the Binding property in your GridColumn. Also, set the Mode to TwoWay in your binding expression to enable editing when you use the Binding property:
<dxg:GridColumn Binding="{Binding Path=SelectedValues, Mode=TwoWay}" ...> <dxg:GridColumn.EditSettings> <dxe:ComboBoxEditSettings ...> <dxe:ComboBoxEditSettings.StyleSettings> <dxe:CheckedComboBoxStyleSettings/> </dxe:ComboBoxEditSettings.StyleSettings> </dxe:ComboBoxEditSettings> </dxg:GridColumn.EditSettings> </dxg:GridColumn>
Note: You can use a custom converter to convert an instance of
List<object>
from an editor to a collection of data items that you use in the underlying property and vice versa (see also: IValueConverter Interface).Change the underlying data item’s property type to Object:
public class GridDataItem { //... public Object SelectedValues { get; set; } //... }
<dxg:GridColumn FieldName="SelectedValues" ...> <dxg:GridColumn.EditSettings> <dxe:ComboBoxEditSettings ...> <dxe:ComboBoxEditSettings.StyleSettings> <dxe:CheckedComboBoxStyleSettings/> </dxe:ComboBoxEditSettings.StyleSettings> </dxe:ComboBoxEditSettings> </dxg:GridColumn.EditSettings> </dxg:GridColumn>
Note: When editors compare objects from the EditValue
property with objects from ItemsSource
, they use these objects’ Equals and GetHashCode methods. In scenarios where EditValue
cannot contain the same objects that ItemsSource
has, you can override these methods to specify your custom logic to determine if certain objects are equal. With this logic, you can compare these objects by one or more fields, instead of by the object’s location in memory (see: Generate Equals and GetHashCode method overrides in Visual Studio).