我似乎找不到正确的语法来允许附加属性用作ComboBox的DisplayMemberPath。
该属性为SelectorSwitchedControl.NameForSelector
它位于命名空间“LocalTest”中,映射到XAML前缀“local”。
这是代码......
<UserControl x:Class="Playground.SelectorSwitchedControlTest.SelectorSwitchedControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:glc="clr-namespace:Playground.CommonControls"
xmlns:local="clr-namespace:Playground.SelectorSwitchedControlTest"
Background="Transparent">
<Border x:Name="MainBorder"
BorderBrush="Gray" BorderThickness="1">
<DockPanel>
<glc:FixedToolBar DockPanel.Dock="Top">
<ComboBox x:Name="MainSelector"
ItemsSource="{Binding Children, ElementName=MainPanel}"
DisplayMemberPath="(local:SelectorSwitchedControl.NameForSelector)" />
</glc:FixedToolBar>
<local:SelectorSwitchedControlPanel x:Name="MainPanel" />
</DockPanel>
</Border>
</UserControl>
...由于某种原因,我发现异常'前缀'本地'不会映射到命名空间。我不知道为什么它会说,就好像我删除'DisplayMemberPath'一行,''标签渲染就像它应该证明命名空间是映射的。
我也尝试了以下所有......
我知道这只是我心灵不工作的那一天,我错过了一些简单的事情,但这让我发疯了!那么正确的语法是什么?
答案 0 :(得分:2)
DisplayMemberPath - 每个项目的显示字符串属性的路径。将其设置为“NameForSelector”,而不是“{Binding NameForSelector}”。
<DockPanel>
<ComboBox x:Name="MainSelector" ItemsSource="{Binding Children}" DisplayMemberPath="NameForSelector" />
</DockPanel>
public class SelectorSwitchedControl
{
public string Name { get; set; }
public string NameForSelector{ get; set; }
}
答案 1 :(得分:1)
我认为在DisplayMemberPath
中使用常规控件的附加属性是不可能的。原因是您使用的属性路径是指在XAML中声明的XML命名空间。通常,当您使用附加属性语法时,在XAML / BAML阅读器创建对象时,可以使用解析器上下文,并且此上下文提供名称空间信息。但是DisplayMemberPath
只是一个字符串,并不捕获此上下文,因此在您的属性路径实际用于创建绑定的位置,此上下文不可用于提供命名空间信息。通过阅读PresentationFramework.dll
中的代码,您可能能够通过目标对象(您的属性所附加的对象)提供上下文,方法是实现IServiceProvider
并返回合适的IXamlTypeResolver
(相关代码从PropertyPath.GetTypeFromName
开始)。
作为更便宜的替代方案,请考虑使用模板或模板选择器而不是DisplayMemberPath
。如果您想使用默认查找机制,请尝试
<ItemTemplate>
<DataTemplate>
<ContextPresenter
Content="{Binding (local:SelectorSwitchedControl.NameForSelector)}"/>
</DataTemplate>
</ItemTemplate>
答案 2 :(得分:0)
正确的值是
DisplayMemberPath="(local:SelectorSwitchedControl.NameForSelector)"
如果这不起作用,那么我会使用Snoop(http://snoopwpf.codeplex.com/)来确保正确设置该值。
这是最简单的工作示例
的Xaml:
<Window x:Class="WPFTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFTest"
Title="MainWindow" Height="350" Width="525" Loaded="MainWindow_Loaded">
<Grid>
<ComboBox Name="cb" DisplayMemberPath="(local:MainWindow.TestValue)" />
</Grid>
代码:
public static string GetTestValue(DependencyObject element)
{
return (string)element.GetValue(TestValueProperty);
}
public static void SetTestValue(DependencyObject element, string value)
{
element.SetValue(TestValueProperty, value);
}
public static readonly DependencyProperty TestValueProperty = DependencyProperty.RegisterAttached("TestValue", typeof(string), typeof(MainWindow), new FrameworkPropertyMetadata(null));
private void MainWindow_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
TextBlock tb = default(TextBlock);
for (int i = 10; i <= 15; i++)
{
tb = new TextBlock();
tb.Text = "Text for " + i;
tb.SetValue(TestValueProperty, "Property For " + i);
this.cb.Items.Add(tb);
}
}