【问题标题】:How to support Dictionary and List in untyped IEnumerable如何在无类型的 IEnumerable 中支持字典和列表
【发布时间】:2015-07-16 13:27:45
【问题描述】:

我有一个“组合框”用户控件/小部件/视图 (Picker),其中 ItemsSource 可以是列表或字典。 ComboBox 在它们之间具有以下属性和 sycs:

SelectedItem : object;
SelectedValue : object;
SelectedValuePath : string;
DisplayMemberPath : string;

“组合框”(Picker) 也有一些内部属性:

SelectedIndex : int;
Items : IList<string>;

ItemsSource 当前没有类型化 IEnumerable - 这样您就可以使用 DictionaryList 从 XAML 填充它。

当我尝试通过知道 SelectedIndex 来设置 SelectedItem 时出现问题。 我不知道Dictionary 的类型(即Dictionary&lt;int, string&gt;)。使用列表可以正常工作:

this.SelectedItem = ((IEnumerable<object>)this.ItemsSource).ToArray()[this.SelectedIndex];

为了使用 Enumerable.ElementAt({index}),我必须将 IEnumerable 转换为类型化字典。它不适用于 IDictionary/Dictionary,而且我似乎也无法转换为 Dictionary&lt;dynamic, dynamic&gt;

此外,我需要从 SelectedItem 更改中同步回 SelectedIndex,这会带来类似的问题。有了一个列表,我就可以做到

this.SelectedIndex = this.ItemsSource.IndexOf(this.SelectedItem);

这不会为 Dictionary 抛出异常,但会返回 -1。

【问题讨论】:

    标签: xamarin.forms c# dictionary combobox ienumerable xamarin.forms


    【解决方案1】:

    我可以给你一个想法,但这绝不是完全的证据,我还没有在你的案例中尝试过。

    假设我有

    Dictionary<int,string> test = new Dictionary<int,string>();
    

    添加了 KVP 值

    test.Add(1,"1");
    test.Add(2,"2");
    test.Add(3,"3");
    

    然后您可以使用反射来生成 IList,然后您可以使用 IndexOf 或使用 Indexer。 如下图

    if (test is IDictionary)
    {
        var list = GetListFromDictionary(test);
        if (list != null)
        {
            Console.WriteLine(list[1]);
            Console.WriteLine(list.IndexOf(new KeyValuePair<int, string>(2,"2")));
        }
    }
    

    GetListFromDictionary 存在

    public IList GetListFromDictionary(IDictionary dict)
    {
    
            var type = dict.GetType();
            var newType = typeof(KeyValuePair<,>);
            var typeArgs = type.GetGenericArguments();
            var contructed  = newType.MakeGenericType(typeArgs);        
            var toListMethod = typeof(Enumerable).GetMethods().First(meth => meth.Name == "ToList");
            var method = toListMethod.MakeGenericMethod(new[] { contructed });
            return method.Invoke(null, new object[] { dict}) as IList;
    
    }
    

    // PCL版本

        public IList GetListFromDictionary(IDictionary dict)
        {
    
            var type = dict.GetType();
            var newType = typeof(KeyValuePair<,>);
            var typeArgs = type.GenericTypeArguments;
            var contructed = newType.MakeGenericType(typeArgs);
            var toListMethod = typeof(Enumerable).GetRuntimeMethods().First(meth => meth.Name == "ToList");
            var method = toListMethod.MakeGenericMethod(new[] { contructed });
            return method.Invoke(null, new object[] { dict }) as IList;
    
        }
    

    【讨论】:

    • 是的,这就像一个魅力。忘了提我虽然推出了 PCL,但我不确定这些反射方法是否有等价物。将进行调查。
    猜你喜欢
    • 2020-07-21
    • 1970-01-01
    • 2017-11-26
    • 2014-05-23
    • 2020-11-28
    • 2022-11-19
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多