我正在尝试通过xaml绑定到Dictionary<Type,string>
。
问题是,[]
标记扩展中的索引器Binding
将其内容解释为字符串。那个案子有某种'unescape-sequence'吗?
<TextBox Text="{Binding theDictionary[{x:Type ns:OnePrettyType}]}" />
(绑定无效,因为{x:Type ns:OnePrettyType}
正在以字符串形式发送)
答案 0 :(得分:12)
如果索引器具有特定类型,则应自动完成转换,因此这应该有效:
{Binding theDictionary[ns:OnePrettyType]}
如果您需要明确的解释,您可以尝试这样的“演员”:
{Binding theDictionary[(sys:Type)ns:OnePrettyType]}
(当然sys
映射到System
名称空间)
那将是理论,但所有这些都行不通。首先,如果使用带有路径的Binding
构造函数,则会忽略强制转换,因为它以某种方式使用PropertyPath
的某个构造函数。您还会收到绑定错误:
System.Windows.Data错误:40:BindingExpression路径错误:'object'''Dictionary`2'上找不到'[]'属性
您需要通过避免PropertyPath
构造函数使其通过类型转换器构造Binding
:
{Binding Path=theDictionary[(sys:Type)ns:OnePrettyType]}
现在这很可能只是抛出异常:
{“路径索引器参数具有无法解析为指定类型的值:'sys:Type'”}
所以很遗憾没有默认的类型转换。然后你可以在XAML中构造一个PropertyPath
并确保传入一个类型,但是这个类并不打算在XAML中使用,如果你尝试也会抛出异常,也非常不幸。
一种解决方法是创建一个执行构造的标记扩展,例如
[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}}}
答案 1 :(得分:3)
更新:我将其留作参考以扩展Bindings
<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);
}
}
这可以扩展为支持使用其他构造函数的内联语法中的更多参数。我仍然可以使用扩展元素语法添加许多参数。
thx to H.B.鼓舞人心的