2017-04-26 33 views
1

我有一個Dictionary<Tuple<SomeEnum, double, string>, double>,我試圖綁定到Xamarin。我只是試圖將價值(雙倍)綁定到一個標籤,沒有什麼特別的花哨。我遇到的問題是我無法弄清楚綁定到Tuple鍵的路徑語法。例如,我知道使用Dictionary<string, double>我只是讓Path="[" + keyString + "]",但我不知道如果我想使用一個元組作爲關鍵要做什麼。即使Microsoft's page on data binding path syntax in C#似乎沒有明確處理這種情況,但它注意到數據綁定到字典與元組中的密鑰在C#

在索引器內部,您可以有多個以逗號(,)分隔的索引器參數。每個參數的類型可以用圓括號指定。例如,您可以有Path="[(sys:Int32)42,(sys:Int32)24]",其中sys映射到System命名空間。

現在,我假設這也適用於單個索引器對象。所以在我的字典案例中,我想我會有類似Path="[(sys:Tuple<SomeEnum, sys:double, sys:string>)???]"的東西,但我不確定???在哪裏。而且我不確定在SomeEnum之前是否需要命名空間。最後,我似乎無法找到更詳細的文檔。所以我會在這些方面提供幫助。

最後,我擔心我可能不得不放棄,切換到Dictionary<string, double>,並讓字符串成爲元組中類型的連接,例如,通過讓每個鍵是string key = SomeEnum.SomeValue + "," + someDouble + "," + someString,但我真的只是喜歡做到這一點。如果有幫助,我願意將Tuple更改爲另一種非字符串類型。也許一些其他不可變的類型?我不是非常精通C#數據綁定超越基礎知識,所以任何幫助或想法都非常感激。

+0

這可能會回答你的問題:HTTP:// stackoverflow.com/a/43209056/880990 –

+0

感謝Olivier,但這是對於新的C#7價值元組類型。我使用的是舊的C#6 Tuple類型,它是可綁定的。見例如https://msdn.microsoft.com/en-us/library/dd386940(v=vs.110).aspx。所以我不確定你發佈的問題能否幫助我。 – TheIntern

回答

1

實際上,多索引器是由數據綁定支持的。語法如下:

<object Path="[index1,index2...]" .../> 
or 
<object Path="propertyName[index,index2...]" .../> 

- PropertyPath XAML Syntax

但是,在創建Tuple內的XAML路徑可以是相當困難的。有2個解決這個:

  1. 創建自定義標記擴展生成Tuple
  2. 創建支持多索引

最簡單和乾淨的詞典可能是解決方案#2。 (PathToDictionary[{ns:Tuple a,b,c}] vs PathToDictionary[a,b,c])。


使用此作爲字典:

public class TripleKeyedDictionary<TKey1, TKey2, TKey3, TValue> : Dictionary<Tuple<TKey1, TKey2, TKey3>, TValue> 
{ 
    public TValue this [TKey1 key1, TKey2 key2, TKey3 key3] 
    { 
     get { return this[Tuple.Create(key1, key2, key3)]; } 
     set { this[Tuple.Create(key1, key2, key3)] = value; } 
    } 
} 

使用示例:PathToDictionary[Banana,b,c]

爲LINQPad完整的示例:

void Main() 
{ 
    var data = new 
    { 
     Lookup = new TripleKeyedDictionary<Fruit, string, string, string> 
     { 
      { Tuple.Create(Fruit.Banana, "b", "c"), "value" } 
     } 
    }; 

    var binding = new Binding("Lookup[Banana,b,c]"); 
    binding.Mode = BindingMode.OneWay; 
    binding.Source = data; 
    binding.FallbackValue = "fallback"; 
    binding.TargetNullValue = "null"; 

    var block = new TextBlock().Dump(); 
    block.SetBinding(TextBlock.TextProperty, binding); 
} 

// Define other methods and classes here 
public enum Fruit 
{ 
    Apple, Banana, Cactus 
} 
public class TripleKeyedDictionary<TKey1, TKey2, TKey3, TValue> : Dictionary<Tuple<TKey1, TKey2, TKey3>, TValue> 
{ 
    public TValue this [TKey1 key1, TKey2 key2, TKey3 key3] 
    { 
     get { return this[Tuple.Create(key1, key2, key3)]; } 
     set { this[Tuple.Create(key1, key2, key3)] = value; } 
    } 
} 
+0

非常優雅的替代解決方案。謝謝! – TheIntern