将SortedList或Dictionary 添加到ResourceDictionary

有没有办法将SortedList或Dictionary添加到ResourceDictionary并通过XAML使用(并绑定!)它到控件?

我试过这个,但我无法弄清楚如何做到这一点:

  ***  

SortedList很简单,因为它不是通用的。

如果一个类实现了IDictionary您可以通过使用x:Key将它们定义为子节点来添加值,以设置应将它们添加到字典中的键。

 xmlns:col="clr-namespace:System.Collections;assembly=mscorlib" 
  Lorem Ipsum Dolor Sit  
   

项目键是这里的字符串,为了获得实际的int,您可以使用自定义标记扩展将字符串解析为int,或者首先将键定义为资源:

 0 1 2 3  Lorem Ipsum Dolor Sit  

然后绑定变得更复杂,因为索引器值需要显式地转换为int,否则将被解释为字符串。

  

由于实现细节,您无法省略Path=


字典并不那么容易,因为它们是通用的,并且(当前)没有简单的内置方法来在XAML中创建通用对象。 但是,使用标记扩展可以通过reflection创建通用对象。

在这样的扩展上实现IDictionary还允许您填充新创建的实例。 这是一个非常粗略的例子

 public class DictionaryFactoryExtension : MarkupExtension, IDictionary { public Type KeyType { get; set; } public Type ValueType { get; set; } private IDictionary _dictionary; private IDictionary Dictionary { get { if (_dictionary == null) { var type = typeof(Dictionary<,>); var dictType = type.MakeGenericType(KeyType, ValueType); _dictionary = (IDictionary)Activator.CreateInstance(dictType); } return _dictionary; } } public override object ProvideValue(IServiceProvider serviceProvider) { return Dictionary; } public void Add(object key, object value) { if (!KeyType.IsAssignableFrom(key.GetType())) key = TypeDescriptor.GetConverter(KeyType).ConvertFrom(key); Dictionary.Add(key, value); } #region Other Interface Members public void Clear() { throw new NotSupportedException(); } public bool Contains(object key) { throw new NotSupportedException(); } //  #endregion } 
  Lorem Ipsum Dolor Sit  

由于传入一个类型化的实例作为键有点痛苦,我选择在IDictionary.Add进行转换,然后将值添加到内部字典中(这可能会导致某些类型的问题)。

由于字典本身是键入的,绑定不应该需要强制转换。