This is a migrated thread and some comments may be shown as answers.

SelectedItems with Converter inside DataForm

1 Answer 341 Views
ListBox
This is a migrated thread and some comments may be shown as answers.
Johannes
Top achievements
Rank 1
Johannes asked on 08 Jun 2015, 09:01 AM

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?

1 Answer, 1 is accepted

Sort by
0
Johannes
Top achievements
Rank 1
answered on 08 Jun 2015, 09:20 AM
In addition I should mention that my Converter AND my Helper class are already working fine. So when my UserControl loads first my Converter is launched to convert a saved string value like "184;185" to an ObservableCollection<DataFieldOption> that consist of two objects of type DataFieldOption with IDs 184 and 185. This value is bound to the SelectedItems property of my Helper class (see XAML code) so the ListBox gets its correct selected items. The problem is that this is never reflected on the UI. My ListBox' always selects the first entry and not the items that correspond to SelectedItems.
Tags
ListBox
Asked by
Johannes
Top achievements
Rank 1
Answers by
Johannes
Top achievements
Rank 1
Share this question
or