2

我似乎找不到正确的语法来允许将附加属性用作组合框的 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'行,''标签呈现就像它应该证明命名空间被映射一样。

我也尝试了以下所有...

  • DisplayMemberPath="local:SelectorSwitchedControl.NameForSelector"
  • DisplayMemberPath="(local:SelectorSwitchedControl.NameForSelector)"
  • DisplayMemberPath="SelectorSwitchedControl.NameForSelector"
  • DisplayMemberPath="(SelectorSwitchedControl.NameForSelector)"
  • DisplayMemberPath="LocalTest.SelectorSwitchedControl.NameForSelector"
  • DisplayMemberPath="(LocalTest.SelectorSwitchedControl.NameForSelector)"

我知道这只是我头脑不灵光的那些日子之一,我错过了一些简单的事情,但这让我发疯了!那么正确的语法是什么?

4

3 回答 3

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; }
    }
于 2013-10-31T08:42:37.470 回答
1

我认为不可能在DisplayMemberPath常规控件中使用附加属性。原因是您使用的属性路径引用了在 XAML 中声明的 XML 命名空间。通常,当您使用附加属性语法时,当 XAML/BAML 阅读器正在创建对象并且此上下文提供命名空间信息时,解析器上下文可用。然而DisplayMemberPath,它只是一个字符串并且不捕获此上下文,因此此上下文不可用于在您的属性路径实际用于创建绑定的位置提供命名空间信息。根据我对 中的代码的阅读PresentationFramework.dll,您可以通过目标对象(您的属性所附加的对象)提供上下文,方法是让它实现IServiceProvider并返回一个合适的IXamlTypeResolver(相关代码从 开始PropertyPath.GetTypeFromName)。

作为更便宜的替代方案,请考虑使用模板或模板选择器而不是DisplayMemberPath. 如果您想使用默认查找机制,请尝试以下内容

<ItemTemplate>
  <DataTemplate>
    <ContextPresenter 
      Content="{Binding (local:SelectorSwitchedControl.NameForSelector)}"/>
  </DataTemplate>
</ItemTemplate>
于 2013-10-30T22:03:45.393 回答
0

正确的值为

DisplayMemberPath="(local:SelectorSwitchedControl.NameForSelector)"

如果这不起作用,那么我将使用 Snoop ( http://snoopwpf.codeplex.com/ ) 来确保正确设置该值。

这是最简单的工作示例

xml:

<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);
        }
    }
于 2013-10-30T21:17:16.700 回答