2012-02-21 17 views
5

xamlからDictionary<Type,string>にバインドしようとしています。タイプのキーを持つ辞書へのXAMLマークアップのバインド

問題は、Bindingマークアップ拡張のインデクサ[]は、その内容を文字列として解釈することです。その場合には何らかの「エスケープシーケンス」がありますか?

<TextBox Text="{Binding theDictionary[{x:Type ns:OnePrettyType}]}" /> 

{x:Type ns:OnePrettyType}文字列として送信されているので、結合が機能しない)

+0

辞書やその他の値にバインドするのではなく、仕事を行うビューモデルにプロパティを公開します。 –

答えて

10

インデクサは、これが動作しなければならないので、変換が自動的に行われるべき特定のタイプがある場合:

{Binding theDictionary[ns:OnePrettyType]} 

を明示的な解釈が必要な場合は、次のような "キャスト"を試すことができます:

{Binding theDictionary[(sys:Type)ns:OnePrettyType]} 

sysはもちろんSystem名前空間にマップされています)

これは理論に過ぎませんが、それはうまくいかないでしょう。まず、パスを取るBindingコンストラクタを使用すると、特定の方法でPropertyPathという特定のコンストラクタを使用するため、キャストは無視されます。また、あなたは、バインディングエラーが発生します。

System.Windows.Data Error: 40 : BindingExpression path error: '[]' property not found on 'object' ''Dictionary`2'

あなたはそれがBindingコンストラクタを回避することにより、型コンバータを介してPropertyPathを構築するために必要があるでしょう:

{Binding Path=theDictionary[(sys:Type)ns:OnePrettyType]} 

これが最も可能性が高いだけ例外がスローされます:

残念ながらデフォルトタイプの変換は行われません。 PropertyPathをXAMLで構築し、型が渡されていることを確認できますが、クラスはXAMLで使用するためのものではありません。また、試してみると例外がスローされます。

1つの回避策は、マークアップ拡張を作成することです。

<Binding> 
    <Binding.Path> 
     <me:PathConstructor Path="theDictionary[(0)]"> 
      <x:Type TypeName="ns:OnePrettyType" /> 
     </me:PathConstructor> 
    </Binding.Path> 
</Binding> 

またはこの

{Binding Path={me:PathConstructor theDictionary[(0)], {x:Type ns:OnePrettyType}}} 
+0

ありがとう、H.B. - あなたは私を驚かせる。あなたが10kを過ぎてから40kに近づいてから数カ月しか経っていないようです。あなたが提供するこれらの質の高い回答に感謝します。これはうまく見える、私はおそらく一度それを試して答えをマークします。 –

+0

聖なる牛、私が何をしたかを見てください。私はいつも「バインディングは拡張可能ではない」と考えました。 [This](http://stackoverflow.com/a/9377298/193320)はそれに近いと感じています。 –

+0

@MarkusHütter:私はこのサイトで時間を過ごしています。私はマークアップ拡張で複数のコンストラクタパラメータを持つことができたことを知っていませんでした。それは、それをインライン展開する興味深い方法です。私は前に 'params'を使ってみましたが、残念なことにコンプライナーはそれを得ていません、完璧でした。バインディングを渡すことについてはわかりませんが、読めるのが少し難しくなると思います。{Binding Path = {me:ParameterPath [(0)]のような ' ...}} ' –

2

のようなアップデート:私は、バインディング

<Grid Width="{my:ParameterBinding {Binding [(0)],Source={x:Static my:SettingsService.Current}, Mode=TwoWay},{x:Type my:LeftPanelWidthSetting}}"/> 
を拡張するための参照のためにこれを任せ、このように使用することができます

[ContentProperty("Parameters")] 
public class PathConstructor : MarkupExtension 
{ 
    public string Path { get; set; } 
    public IList Parameters { get; set; } 

    public PathConstructor() 
    { 
     Parameters = new List<object>(); 
    } 
    public PathConstructor(string path, object p0) 
    { 
     Path = path; 
     Parameters = new[] { p0 }; 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return new PropertyPath(Path, Parameters.Cast<object>().ToArray()); 
    } 
} 

それは、これは追加のコンストラクタをインライン構文でより多くのパラメータをサポートする拡張だろう

[ContentProperty("Parameters")] 
public class ParameterBinding : MarkupExtension 
{ 
    public Binding Binding { get; set; } 
    public IList Parameters { get; set; } 

    public ParameterBinding() 
    { 
     Parameters = new List<object>(); 
    } 

    public ParameterBinding(Binding b, object p0) 
    { 
     Binding = b; 
     Parameters = new []{p0}; 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     Binding.Path = new PropertyPath(Binding.Path.Path, Parameters.Cast<object>().ToArray()); 
     return Binding.ProvideValue(serviceProvider); 
    } 
} 

の背後にあるコードです。私はまだ拡張要素の構文で多くのパラメータを追加する能力を残しました。

thxからH.B.これを刺激するため

関連する問題