2012-02-25 31 views
10

有沒有方法可以將SortedList或Dictionary添加到ResourceDictionary中,並通過XAML使用(並綁定到)控件?將SortedList或Dictionary <int, string>添加到ResourceDictionary

我試過,但我無法弄清楚如何做到這一點:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:sys="clr-namespace:System;assembly=mscorlib" 
    xmlns:coll="clr-namespace:System.Collections.Generic;assembly=mscorlib"> 

    <x:Array x:Key="test" 
      Type="sys:Object"> 
     <coll:KeyValuePair>***</coll:KeyValuePair> 
    </x:Array> 
+0

'X:如果您添加*值*爲了,你想補充Array'就可以了第一個'',它會得到指數'0'等,當時的結合能使用'[0]'指向索引器。 – 2012-02-26 03:10:37

+0

@SeToY,請回答問題。 – Shimmy 2012-02-26 03:42:05

+0

@Shimmy這是半夜在這裏,我去睡覺了;-) – SeToY 2012-02-26 09:59:44

回答

16

SortedList很容易,因爲它是不通用的。

如果某個類實現了IDictionary,則可以使用x:Key將它們定義爲子節點來添加值,以設置它們應添加到字典的鍵。

xmlns:col="clr-namespace:System.Collections;assembly=mscorlib" 
<col:SortedList x:Key="list"> 
    <sys:String x:Key="0">Lorem</sys:String> 
    <sys:String x:Key="1">Ipsum</sys:String> 
    <sys:String x:Key="2">Dolor</sys:String> 
    <sys:String x:Key="3">Sit</sys:String> 
</col:SortedList> 
<!-- Usage: --> 
<ContentControl Content="{Binding [0], Source={StaticResource list}}" /> 

項鍵是字符串在這裏,讓你可以使用自定義標記擴展其解析字符串爲int實際整數,或者先定義鍵作爲資源:

<sys:Int32 x:Key="key1">0</sys:Int32> 
<sys:Int32 x:Key="key2">1</sys:Int32> 
<sys:Int32 x:Key="key3">2</sys:Int32> 
<sys:Int32 x:Key="key4">3</sys:Int32> 

<col:SortedList x:Key="list"> 
    <sys:String x:Key="{StaticResource key1}">Lorem</sys:String> 
    <sys:String x:Key="{StaticResource key2}">Ipsum</sys:String> 
    <sys:String x:Key="{StaticResource key3}">Dolor</sys:String> 
    <sys:String x:Key="{StaticResource key4}">Sit</sys:String> 
</col:SortedList> 

綁定然後變得更加複雜,因爲索引器值需要顯式轉換爲int否則會被解釋爲字符串。

<ContentControl Content="{Binding Path=[(sys:Int32)0], 
            Source={StaticResource list}}"/> 

無法省略Path=因爲implementation detail的。


字典是不那麼容易,因爲它們是通用的,有(目前)沒有簡單的內置的方式來創建XAML通用對象。但是,使用標記擴展可以通過反射來創建通用對象。

在這樣的擴展上實現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(); 
    } 
    // <Many more members that do not matter one bit...> 
    #endregion 
} 
<me:DictionaryFactory x:Key="dict" KeyType="sys:Int32" ValueType="sys:String"> 
    <sys:String x:Key="0">Lorem</sys:String> 
    <sys:String x:Key="1">Ipsum</sys:String> 
    <sys:String x:Key="2">Dolor</sys:String> 
    <sys:String x:Key="3">Sit</sys:String> 
</me:DictionaryFactory> 

作爲傳遞一個類型的實例作爲關鍵是有點痛的我選擇了做轉換在IDictionary.Add前值被添加到內部字典,而不是(這可能會導致某些類型的問題)。

由於字典本身是鍵入的,綁定應該而不是需要強制轉換。

<ContentControl Content="{Binding [0], Source={StaticResource dict}}" /> 
+0

謝謝你這個真棒的答案,這幫了我很多:) – SeToY 2012-02-26 10:00:31

+0

@SeToY:不客氣,我認爲這是一個有趣的問題。 – 2012-02-26 16:45:22

+0

@ H.B。順便說一句:恭喜40k – 2012-02-28 00:22:41

相關問題