Hi,
I have struggled to create a Field template for a List<Item> in XamDataGrid. For the purpose I have tried with both ComboBoxField and TemplateField, and could not succeed with both.
Goal:
My goal is to create a templated field (Test 2)
where a text represents the items in the list, and when in edit mode, to have a ComboBox where items are listed with CheckBoxes to select.
So far I have managed to create the field where the correct data is shown, but when in edit mode, it doesn't really work.
//DISPLAY TEMPLATE var displayTxBlFactory = new FrameworkElementFactory(typeof(TextBlock)); var displayTxBlBinding = new Binding() {Converter = new EnumListToStringConverter()}; displayTxBlFactory.SetBinding(TextBlock.TextProperty, displayTxBlBinding); displayTxBlFactory.Name = "EnumDisplayTextBlock"; var displayTxBlTemplate = new DataTemplate {VisualTree = displayTxBlFactory}; DisplayTemplate = displayTxBlTemplate; //EDITING TEMPLATE //**CHECK BOX** var editCbFactory = new FrameworkElementFactory(typeof(CheckBox)); var editCbBinding = new Binding(".") {Converter = new CheckBoxIsCheckedToEnumListConverter(), ConverterParameter = EnumSource}; editCbFactory.SetBinding(ToggleButton.IsCheckedProperty, editCbBinding); var editCbTemplate = new DataTemplate {VisualTree = editCbFactory}; //**COMBO BOX** var editCmbFactory = new FrameworkElementFactory(typeof(ComboBox)); editCmbFactory.SetValue(ItemsControl.ItemsSourceProperty, ItemsSource); editCmbFactory.SetValue(ItemsControl.ItemTemplateProperty, editCbTemplate); var editCmbTemplate = new DataTemplate() {VisualTree = editCmbFactory}; EditTemplate = editCmbTemplate;
The above code is used to create the DisplayTemplate and EditTemplate of the TemplateField.
My struggle is how to provide the bound data to the checkboxes in the template.
public class CisItem : INotifyPropertyChanged { public CisItem(int id, string name, int enumId, List<CisItemEnum> enums) { _itemId = id; _itemName = name; _enumId = enumId; _cisItemEnums = enums; } public string ItemName {get ; set;} public int ItemId {get ; set;} public int EnumId {get ; set;} public CisItemEnum CisItemEnum {get ; set;} public string SelectedEnums {get ; set;} public List<CisItemEnum> SelectedEnums1 {get ; set;} public List<CisItemEnum> SelectedEnums2 {get ; set;} public List<CisItemEnum> CisItemEnums => _cisItemEnums; }
Above is the structure of the item that is used to bind to the grid.
The TemplateField is bound to the SelectedEnums2 property.the property is of type List<CisItemEnum>.
Note: I am not interested in the Add and Remove methods of List or ObservableCollection.I need to call the setter of the property.
Question:
How can I make a template for such a field that it is either by checking/unchecking the checkboxes or when field editing has ended it calls the setter of the property with a new list ?
Sample:
3652.WpfAllPurposesTest.rar
Hello Nawed,
I have been investigating into the sample project you have provided, but I am going to provide a sample project of my own to demonstrate how to have a multi-select combo box / XamComboEditor within the XamDataGrid, as this typically is a rather complicated operation to have this work reliably.
The first thing I would recommend doing is having your TemplateField be Name-bound to a string property that will represent what will be in the combo when your multiple selection is made, and using the SelectedItems property of the Infragistics.Controls.Editors.XamComboEditor, bind to this property on your data item. Using a converter, you will need to parse the string selection into an ObservableCollection<object> that will contain the items. If you keep the types in this conversion consistent, you will find this to be much easier. That is, since you are binding to a string property on the TemplateField, you should have an ItemsSource of strings, as this will make things much easier.
The sample project is also including a Behavior<XamComboEditor> that handles the SelectionChanged event on the combo. Here, you can catch your selections as they are made and push the string value back to your underlying string property. This will fire the converter attached to your SelectedItems property as well, which will give a sort of “handshake” between your Behavior and your converter that allows the multiple selection of the XamComboEditor to work and not get lost in the virtualization of the XamDataGrid as it scrolls.
This may seem rather complicated, but at the time of writing this, it is the only way I have seen the multi-select XamComboEditor work in the XamDataGrid and retain its selection when editing.
I am attaching a sample project to demonstrate. I hope this helps you.
Please let me know if you have any other questions or concerns on this matter.
3377.XDGMultiSelectDropDownCase.zip
Hello Andrew,
Thank for the reply and sample. I can see the logic in binding the field to a string and providing a collection of strings to the ComboEditor, but in our real project I cannot use a string with all the names. The selection can become very big, and that is the reason that we would like to only show comma separated IDs in the string. But in the drop down of the ComboEditor we need to show IDs and names: Like below:
So far I have been able to achieve the "viewing" by separating the DisplayTemplate and EditTemplate of the TemplateField and providing a list of "class" to the ItemsSource of ComboEditor and setting the DisplayMemberPath.
And Selecting items from the ComboBox does also update the underlying property of the VM, but I cannot make the checkboxes show the selections correctly.
Where is the comparing happening ? The converter is providing a observable collection of strings? and what else is happening ?
I am under the impression that by your question of “where is the comparing happening,” you mean to ask when the converter is firing? If this is the case, the converter should be firing when you enter edit mode, as that is when the underlying XamComboEditor will be “created” for the cell.
The reason I had recommended to use a collection of strings for use with the XamComboEditor is because by using a complex item for the ItemsSource of the XamComboEditor, you will need to return an ObservableCollection<object> containing those items from your converter in order to have them retain their selection. These items will also need to be the same instance of the items that are in your ItemsSource or they won’t select as they will be considered a new instance of your custom class. This is why the ObservableCollection<object> containing the strings in the sample project I sent you works to select the items, as the strings do not need to be the same instance of the items in the combo.
I hope this helps to shed some light on the selection in the XamComboEditor. Please let me know if you have any other questions or concerns on this matter.
Ahh, Perfect.Changing the converter to IMultiValueConverter and providing both the List of items and the binding property did the trick.
Looks beautiful. Many thanks.