XAML标记绑定到字典式类型的关键绑定、字典、标记、关键

2023-09-03 02:13:57 作者:下课铃声才是中国好声音

我想绑定到词典<型号,串>通过XAML

现在的问题是,索引 [] 绑定标记扩展跨$ P $点是为内容串。是否有某种反向转义序列的那种情况?

The problem is, the indexer [] in the Binding markup extension interprets it's content as string. Is there some kind of 'unescape-sequence' for that case?

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

(绑定不工作,因为 {X:NS类型:一prettyType} 正在发送的字符串)

(Binding doesn't work because {x:Type ns:OnePrettyType} is being sent as string)

推荐答案

如果索引器都有特定的类型转换应该自动完成所以这应该工作:

If the indexer has a specific type the conversion should be done automatically so this should work:

{Binding theDictionary[ns:OnePrettyType]}

如果你需要一个明确的跨pretation可以尝试投是这样的:

If you need an explicit interpretation you can try a "cast" like this:

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

(这里的 SYS 映射到进程的系统命名空间)

(Where sys is mapped to the System namespace of course)

这将是理论,但所有这一切将无法正常工作。首先,如果你使用绑定构造函数的路径中投将被忽略,因为它使用的PropertyPath以一定的方式。你也将获得一个绑定错误:

That would be the theory but all of that won't work. First of all if you use the Binding constructor that takes a path the cast will be ignored as it uses a certain constructor of PropertyPath in a certain way. Also you will get a binding error:

System.Windows.Data错误:40:BindingEx pression路径错误:'[]'属性不是'对象'发现''Dictionary`2

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

您需要使其构造的PropertyPath 通过类型转换器通过避免绑定构造器:

You would need to make it construct the PropertyPath via the type converter by avoiding the Binding constructor:

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

现在,这将极有可能只是抛出一个异常:

Now this will most likely just throw an exception:

{路径索引器参数的值,它不能被解析为指定的类型:SYS:类型}

{"Path indexer parameter has value that cannot be resolved to specified type: 'sys:Type'"}

因此​​,有不幸的是,没有默认的类型转换正在进行。然后,您可以构造一个的PropertyPath 在XAML,并确保一个类型传入,但类并不意味着在XAML中使用,如果你尝试将抛出一个异常,也很不幸。

So there unfortunately is no default type conversion going on. You could then construct a PropertyPath in XAML and make sure a type is passed in, but the class is not meant to be used in XAML and will throw an exception if you try, also very unfortunate.

一种解决方法是创建一个标记扩展由它来完成建设,如:

One workaround would be to create a markup extension which does the construction, e.g.

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

然后可以使用这样的:

Which then can be used like this:

<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}}}