7

Dictionary<Type,string>xaml経由でバインドしようとしています。

問題は、マークアップ拡張機能のインデクサー[]Bindingコンテンツを文字列として解釈することです。その場合、ある種の「unescape-sequence」はありますか?

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

{x:Type ns:OnePrettyType}(文字列として送信されているため、バインディングは機能しません)

4

2 に答える 2

12

インデクサーに特定のタイプがある場合、変換は自動的に行われる必要があるため、これは機能するはずです。

{Binding theDictionary[ns:OnePrettyType]}

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

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

(もちろん、名前空間にsysマップされている場所)System

それは理論ですが、それはすべてうまくいきません。まずBinding、パスをとるコンストラクターを使用する場合PropertyPath、特定の方法での特定のコンストラクターを使用するため、キャストは無視されます。また、バインディングエラーが発生します。

System.Windows.Dataエラー:40:BindingExpressionパスエラー:'[]'プロパティが'オブジェクト'''辞書`2'に見つかりません

PropertyPathコンストラクターを避けて、型コンバーターを介してコンストラクターを構築する必要がありますBinding

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

これで、ほとんどの場合、例外がスローされます。

{"パスインデクサーパラメーターに、指定されたタイプに解決できない値があります:'sys:Type'"}

そのため、残念ながら、デフォルトの型変換は行われていません。次にPropertyPath、XAMLでを作成し、型が渡されることを確認できますが、クラスはXAMLで使用されることを意図しておらず、試行すると例外がスローされます。これも非常に残念です。

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

[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());
    }
}

次に、次のように使用できます。

<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}}}
于 2012-02-21T02:55:33.953 に答える
3

更新:バインディングを拡張するための参照用にこれを残します

<Grid Width="{my:ParameterBinding {Binding [(0)],Source={x:Static my:SettingsService.Current}, Mode=TwoWay},{x:Type my:LeftPanelWidthSetting}}"/>

それが背後にあるコードです

[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);
    }
}

これは、追加のコンストラクターを使用してインライン構文でより多くのパラメーターをサポートするように拡張できます。拡張要素構文を使用して多くのパラメーターを追加する機能はまだ残されています。

これを刺激してくれたHBにthx

于 2012-02-21T12:04:28.937 に答える