简体   繁体   中英

C# - Convert IEnumerable to Dictionary<object,string>

I am building a WPF UserControl . For this I implemented an ItemSource DependecyProperty like this:

private IEnumerable MisItems;
    public IEnumerable ItemsSource
    {
        get { return (IEnumerable)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(TextBoxAutoComplete), new PropertyMetadata(new PropertyChangedCallback(OnItemsSourcePropertyChanged)));

    private static void OnItemsSourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var control = sender as TextBoxAutoComplete;
        if (control != null)
            control.OnItemsSourceChanged((IEnumerable)e.OldValue, (IEnumerable)e.NewValue);
    }

    private void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
    {
        MisItems = newValue;
        // Remove handler for oldValue.CollectionChanged
        var oldValueINotifyCollectionChanged = oldValue as INotifyCollectionChanged;

        if (null != oldValueINotifyCollectionChanged)
        {
            oldValueINotifyCollectionChanged.CollectionChanged -= new NotifyCollectionChangedEventHandler(newValueINotifyCollectionChanged_CollectionChanged);
        }
        // Add handler for newValue.CollectionChanged (if possible)
        var newValueINotifyCollectionChanged = newValue as INotifyCollectionChanged;
        if (null != newValueINotifyCollectionChanged)
        {
            newValueINotifyCollectionChanged.CollectionChanged += new NotifyCollectionChangedEventHandler(newValueINotifyCollectionChanged_CollectionChanged);
        }

    }

    void newValueINotifyCollectionChanged_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        //Do your stuff here.
    }

The ItemsSource property is represented by a IEnumerable Object. Now I need to convert it to a Dictionary<object,string > in this function:

protected SearchResult DoSearch(string searchTerm)
    {
        if (!string.IsNullOrEmpty(searchTerm))
        {
            SearchResult sr = new SearchResult();
            //var ItemsText = MisItems.GetType();
            var p = (List<string>)MisItems;

             /*sr.Results = ItemsText.Select((x, i) => new { x, i }).Where(x=>x.ToString().ToUpper().Contains(searchTerm.ToUpper()))
            .ToDictionary(a => (object)a.i, a => a.x);*/

            return sr;
        }
        else return new SearchResult();           
    }

How can i make the transition?

EDIT More info: My viewmodel has this property:

public List<EnumeradorWCFModel> Clientes { get; set; }

The data for this property is returned by a WCF service :

Clientes = _svc.Clientes_Enum(sTicket, "");

Then I wanted my UserControl to bind to this property. I create my control like this:

<autocomplete:TextBoxAutoComplete x:Name="Clientes"  ItemsSource = "{Binding Path=Clientes}" DisplayMemberPath="Descripcion" Height="25"/>

[s]Alright. You posted a lot of code (that I personally think is unnecessary for what you're trying to do).

Let's slim it down.

You have an IEnumerable<string> to start out, correct? Good.

There's a ToDictionary() extension method in the LINQ libraries. Documentation is here .

So what you need to do is the following:

IEnumerable<string> myEnumerableOfStrings = new List<string>();

Dictionary<object, string> dictionary = myEnumerableOfStrings.ToDictionary(value => (object) value);

And here's a Fiddle as an example.

Alright, so we have just an IEnumerable with no strong type. (First I've ever seen or heard of this being done, but the same principles should apply.)

We need to create a local dictionary and iterate over that collection.

var myDictionary = new Dictionary<object, string>();
IEnumerable myCollection = new List<string>();

foreach(var item in myCollection)
{
    // This might be fun if you get two of the same object in the collection.
    // Since this key is based off of the results of the GetHashCode() object in the base object class.
    myDictionary.Add((object) item, item.ToString());
}

Here's an example of that.

The above answer's example for ToDictionary extension, is a List of a primitive type (string), I would like to demonstrate converting a List of a complex type (class) into dictionary.

This overload is constructing a dictionary out of keySelector function and elementSelector function ( docs ):

public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector);

For example:

public class FooClass 
{
    public int FooKey { get; set; }
    public string FooValue { get; set; }
}

IENumerable<FooClass> foos = new List<FooClass>();
IDictionary<int, string> dict = foos.ToDictionary<int, string>(x=>x.FooKey, x=>x.FooValue);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM