.net 使用类型为的键绑定到字典的XAML标记

.net 使用类型为的键绑定到字典的XAML标记,.net,wpf,xaml,markup-extensions,.net,Wpf,Xaml,Markup Extensions,我正试图通过xaml绑定到字典 问题是,绑定标记扩展中的索引器[]将其内容解释为字符串。对于这种情况,是否存在某种“unescape序列” <TextBox Text="{Binding theDictionary[{x:Type ns:OnePrettyType}]}" /> (绑定不起作用,因为{x:Type ns:OnePrettyType}正在作为字符串发送)如果索引器具有特定类型,则应自动完成转换,因此这应该起作用: {Binding theDictionary[ns

我正试图通过xaml绑定到
字典

问题是,
绑定
标记扩展中的索引器
[]
将其内容解释为字符串。对于这种情况,是否存在某种“unescape序列”

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


(绑定不起作用,因为
{x:Type ns:OnePrettyType}
正在作为字符串发送)

如果索引器具有特定类型,则应自动完成转换,因此这应该起作用:

{Binding theDictionary[ns:OnePrettyType]}
如果您需要明确的解释,您可以尝试这样的“强制转换”:

{Binding theDictionary[(sys:Type)ns:OnePrettyType]}
<Binding>
    <Binding.Path>
        <me:PathConstructor Path="theDictionary[(0)]">
            <x:Type TypeName="ns:OnePrettyType" />
        </me:PathConstructor>
    </Binding.Path>
</Binding>
(其中,
sys
当然映射到
System
名称空间)

这是理论,但所有这些都行不通。首先,如果使用采用路径的
绑定
构造函数,则cast将被忽略,因为它以特定方式使用的特定构造函数。此外,还将出现绑定错误:

System.Windows.Data错误:40:BindingExpression路径错误:“[]”在“对象”字典“2”上找不到属性

您需要让它通过类型转换器构造
PropertyPath
,避免使用
绑定
构造函数:

{Binding Path=theDictionary[(sys:Type)ns:OnePrettyType]}
现在,这很可能只是抛出一个异常:

{“路径索引器参数的值无法解析为指定的类型:'sys:type'”}

因此,不幸的是,没有进行默认类型转换。然后,您可以在XAML中构造一个
PropertyPath
,并确保传入了一个类型,但该类并不打算在XAML中使用,如果您尝试,它将抛出一个异常,这也是非常不幸的

一种解决方法是创建一个标记扩展来进行构造,例如

[ContentProperty(“参数”)]
公共类路径构造函数:MarkupExtension
{
公共字符串路径{get;set;}
公共IList参数{get;set;}
公共路径构造函数()
{
参数=新列表();
}
公共路径构造函数(字符串路径,对象p0)
{
路径=路径;
参数=新[]{p0};
}
公共覆盖对象ProviderValue(IServiceProvider服务提供程序)
{
返回新的PropertyPath(路径,Parameters.Cast().ToArray());
}
}
然后可以这样使用:

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

更新:我把它留作扩展绑定的参考

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

这就是背后的代码

[ContentProperty(“参数”)]
公共类参数绑定:MarkupExtension
{
公共绑定{get;set;}
公共IList参数{get;set;}
公共参数绑定()
{
参数=新列表();
}
公共参数绑定(绑定b,对象p0)
{
绑定=b;
参数=新[]{p0};
}
公共覆盖对象ProviderValue(IServiceProvider服务提供程序)
{
Binding.Path=newpropertyPath(Binding.Path.Path,Parameters.Cast().ToArray());
返回绑定。ProvideValue(serviceProvider);
}
}
这将是可扩展的,以支持更多内联语法中的参数和其他构造函数。我仍然能够使用扩展元素语法添加许多参数


thx to H.B.为了激发这一点

而不是绑定到字典和其他值,请在viewmodel上公开一个属性,为您提供帮助。谢谢,H.B.-您让我感到惊讶。从你通过10公里到现在接近4万公里,似乎只有几个月了。感谢您提供的所有这些高质量的答案。这看起来不错,一旦我试过,我可能会记下答案。天哪,看看我做了什么。我一直认为“绑定是不可扩展的”。感觉很接近。@MarkusHütter:我在这个网站上花的时间太多了。我不知道在标记扩展中可以有多个构造函数参数,谢谢,这是一种有趣的内联方式。我之前尝试过使用
params
,但不幸的是,compliner没有得到它,它本来是完美的。虽然我不知道如何传递绑定,但我认为这会使它更难阅读,我只会坚持在
路径中使用它,就像
{binding Path={me:ParameterPath[(0)],…}
我认为你的可读性是正确的,我可能会使用你的解决方案,添加了带参数的构造函数,仅仅在视图模型上公开一个属性是没有意义的?i、 e.
public-onepretty键入类型{get{返回字典[0];}}//并检查错误