C# 如何将附加属性绑定到组合框的DisplayMemberPath?
我似乎找不到允许附加属性用作组合框的DisplayMemberPath的正确语法 属性为SelectorSwitchedControl.NameForSelectorC# 如何将附加属性绑定到组合框的DisplayMemberPath?,c#,wpf,binding,C#,Wpf,Binding,我似乎找不到允许附加属性用作组合框的DisplayMemberPath的正确语法 属性为SelectorSwitchedControl.NameForSelector 它位于映射到XAML前缀“local”的名称空间“LocalTest”中 这是密码 <UserControl x:Class="Playground.SelectorSwitchedControlTest.SelectorSwitchedControl" xmlns="http://schemas.microsoft
它位于映射到XAML前缀“local”的名称空间“LocalTest”中 这是密码
<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>
…由于某种原因,这给了我一个异常“Prefix'local'没有映射到命名空间”。我不确定为什么它会说,好像我删除了“DisplayMemberPath”行,“”标记的呈现就像它应该证明命名空间已映射一样
我也尝试了以下所有方法
- DisplayMemberPath=“本地:SelectorSwitchedControl.NameForSelector”
- DisplayMemberPath=“(本地:SelectorSwitchedControl.NameForSelector)”
- DisplayMemberPath=“SelectorSwitchedControl.NameForSelector”
- DisplayMemberPath=“(SelectorSwitchedControl.NameForSelector)”
- DisplayMemberPath=“LocalTest.SelectorSwitchedControl.NameForSelector”
- DisplayMemberPath=“(LocalTest.SelectorSwitchedControl.NameForSelector)”
DisplayMemberPath="(local:SelectorSwitchedControl.NameForSelector)"
如果这不起作用,那么我将使用Snoop()确保正确设置该值
下面是最简单的工作示例
Xaml:
代码:
公共静态字符串GetTestValue(DependencyObject元素)
{
返回(字符串)元素.GetValue(TestValueProperty);
}
公共静态void SetTestValue(DependencyObject元素,字符串值)
{
SetValue(TestValueProperty,value);
}
公共静态只读DependencyProperty TestValueProperty=DependencyProperty.RegisterAttached(“TestValue”、typeof(string)、typeof(MainWindow)、new FrameworkPropertyMetadata(null));
已加载私有void主窗口(对象发送器,System.Windows.RoutedEventArgs e)
{
TextBlock tb=默认值(TextBlock);
对于(int i=10;i我认为在DisplayMemberPath
中不可能将附加属性与常规控件一起使用。原因是您使用的属性路径引用在XAML中声明的XML命名空间。通常,当您使用附加属性语法时,当XAML/BAML读取器s创建对象,此上下文提供命名空间信息。但是,DisplayMemberPath
只是一个字符串,不能捕获此上下文,因此在实际使用属性路径创建绑定时,此上下文无法提供命名空间信息。从我在Pres中阅读的代码entationFramework.dll
,您可以通过目标对象(您的属性所附加的对象)提供上下文,方法是让它实现IServiceProvider
,并返回合适的IXamlTypeResolver
(相关代码从PropertyPath.GetTypeFromName
开始)
作为一种更便宜的替代方案,考虑模板或模板选择器,而不是<代码> DePaseMeistPuth。如果您想使用默认查找机制,请尝试沿
行的一些东西。
<ItemTemplate>
<DataTemplate>
<ContextPresenter
Content="{Binding (local:SelectorSwitchedControl.NameForSelector)}"/>
</DataTemplate>
</ItemTemplate>
DisplayMemberPath-每个项的显示字符串属性的路径。将其设置为“NameForSelector”,而不是“{Binding NameForSelector}”
公共类选择器开关控件
{
公共字符串名称{get;set;}
选择器{get;set;}的公共字符串名称
}
我在你的代码中没有看到{Binding}
这个词。这是一个奇怪的词……就我个人而言,我会选择displaymberpath=“(local:SelectorSwitchedControl.NameForSelector)”
。但是,在快速搜索之后,我在绑定
和显示成员路径
上找不到任何有用的内容。我检查了MSDN,可以确认显示成员路径
属性是一个依赖属性
,它使用绑定属性
设置为真
。是否设置了数据控制text=“{StaticResource SomeSource}”
和ItemsSource=“{Binding}”
?HighCore,我也尝试过这个…'DisplayMemberPath=“{Binding(local:SelectorSwitchedControl.NameForSelector)}”'但当我这样做时,我得到运行时异常'Prefix'local'没有映射到名称空间。'显然是这样。这实际上是我们使用的第一种方法,但ComboBox的ItemTemplate不适用于主选择区域。要做到这一点,您必须完全替换ComboBox的模板,这似乎有些过分了如果没有人给出更好的答案,你将获得投票权。我明白了。如果你的组合框IsReadOnly
,并且你的项目是已知的特定类型,你可以尝试将上面这样的数据模板和适当的DataType
放入窗口资源中。但它不是“NameF”orSelector“…它是“SelectorSwitchedControl.NameForSelector”。我认为如果没有完全限定的路径,内部反射将找不到它。(我也同意绑定。这是对HighCore回答的回应,我不同意。)实际上,在子集合中,所有项都应具有Selector SwitchedControl.NameForSelector属性。不要使用“local:”对于set-DisplayMemberPath。当设置ItemsSource时,您可以看到带有正确属性名称的帮助弹出窗口。我检查了我的代码,所有工作正常。实际上,我不确定我以前是如何漏掉这一点的,但您的代码没有使用附加属性。您使用的是标准CLR属性,这是一个完全不同的beast,因此这不是一个应用程序e答案
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);
}
}
<ItemTemplate>
<DataTemplate>
<ContextPresenter
Content="{Binding (local:SelectorSwitchedControl.NameForSelector)}"/>
</DataTemplate>
</ItemTemplate>
<DockPanel>
<ComboBox x:Name="MainSelector" ItemsSource="{Binding Children}" DisplayMemberPath="NameForSelector" />
</DockPanel>
public class SelectorSwitchedControl
{
public string Name { get; set; }
public string NameForSelector{ get; set; }
}