SelectedItems with Converter inside DataForm

2 posts, 0 answers
  1. Johannes
    Johannes avatar
    66 posts
    Member since:
    Dec 2012

    Posted 08 Jun 2015 Link to this post

    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?

  2. Johannes
    Johannes avatar
    66 posts
    Member since:
    Dec 2012

    Posted 08 Jun 2015 Link to this post

    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.
  3. UI for WPF is Visual Studio 2017 Ready
Back to Top