I'm in need to display a RadListBox with some Items as ItemsSource. Those items are of type DataFieldOption and the have properties ID (int) and Name (string).
Here are some examples:
DataFieldOption 1: ID = 184, Name = "German"
DataFieldOption 2: ID = 185, Name = "English"
DataFieldOption 3: ID = 186, Name = "French"
...
The SelectionMode of my ListBox is Multiple. I already read the Telerik blog about how to handle the SelectedItems property so I created the necessary helper class and named it ListBoxSelectedItemsHelper.
public class ListBoxSelectedItemsHelper { #region Fields public static readonly DependencyProperty SelectedItemsProperty; #endregion #region Constructors static ListBoxSelectedItemsHelper() { SelectedItemsProperty = DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), typeof(ListBoxSelectedItemsHelper), new FrameworkPropertyMetadata(null, OnSelectedItemsChanged)); } #endregion #region Methods #region DependencyProperty Methods #region CallBack private static void OnSelectedItemsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { var listBox = sender as RadListBox; if (listBox != null) { IList selectedItems = GetSelectedItems(listBox); if (selectedItems != null) { listBox.SelectedItems.Clear(); foreach (var item in selectedItems) { listBox.SelectedItems.Add(item); } } } } #endregion #region Getter/Setter public static IList GetSelectedItems(DependencyObject d) { return (IList) d.GetValue(SelectedItemsProperty); } public static void SetSelectedItems(DependencyObject d, IList value) { d.SetValue(SelectedItemsProperty, value); } #endregion #endregion #endregion
I must use this ListBox inside RadDataForm and I need to get the ListBox' selected items as one single string value with the help of a converter. So if three ListBox entries are selected SelectedItems will become an ObservableCollection with three objects in it. This is achieved by using the helper class from above. Now it's getting tricky. I want to use a converter that converts that ObservableCollection to a string value. Looking at the example values at the begining of my post this means: If German and French are selected in the ListBox, SelectedItems becomes ObservableCollection with two objects and this should get converted to "184;186" (the objects IDs separated by ';').
Here is my converter (it already works):
public class DataFieldOptionConverter : DependencyObject, IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Length == 2) { var dataFieldOptions = values[0] as IList<IDataFieldOptionDataItemViewModel>; var stringValue = values[1] as string; // if (dataFieldOptions != null && String.IsNullOrEmpty(stringValue) == false) { var parts = stringValue.Split(';'); if (parts.Any()) { var result = new List<IDataFieldOptionDataItemViewModel>(); foreach (var part in parts) { var dfo = dataFieldOptions.SingleOrDefault(x => (System.Convert.ToString(x.ID) == part)); if (dfo != null) { result.Add(dfo); } } return result; } } } // Konvertierung fehlgeschlagen return DependencyProperty.UnsetValue; }
It is a MultiValueConverter to pass in a list of all selectable items (see type DataFieldOption above) and a string value of format "184;186" to check which items are selected. This is my XAML code:
<t:DataFormDataField Label="{Binding DataField.Label, Mode=OneWay}" Description="{Binding DataField.ToolTip, Mode=OneWay}" DataMemberBinding="{Binding Value, Mode=OneWay}"> <tx:CustomRadListBox ItemsSource="{Binding DataField.DataFieldOptions, Mode=OneWay}" DisplayMemberPath="Name" SelectedValuePath="ID" SelectionMode="Multiple"> <tx:ListBoxSelectedItemsHelper.SelectedItems> <MultiBinding Converter="{StaticResource DataFieldOptionConverter}" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"> <Binding Path="DataField.DataFieldOptions" /> <Binding Path="Value" /> </MultiBinding> </tx:ListBoxSelectedItemsHelper.SelectedItems> </tx:CustomRadListBox></t:DataFormDataField>
I tried to get this to work for days now and I'm really running out of ideas. What I need is a RadListBox with SelectionMode = multiple and I want to save the users selection as a single string value in a database. Later that value is read from the database (for example "184;186;188") and it has to be converted back to a list of selected items so the ListBox gets back to its saved state. And all this inside RadDataForm. Can you provide any help on this?