WPF 中带有索引器的 DisplayMemberPath

DisplayMemberPath with Indexer in WPF

起始情况

我想在 ComboBox 中显示 ICameraInfo 的列表。
ICameraInfo 是一个接口,可以为您提供相机的许多信息。您使用 indexer.

获取每个信息

在我的例子中,我想在 ComboBox 中显示参数 ICameraInfo[CameraInfoKey.FriendlyName](CameraInfoKey 是静态的 class)。

代码

在 ViewModel 中:

using Basler.Pylon;
...
public List<ICameraInfo> CamerasFound { get => CameraFinder.Enumerate(); }

在视图中:

<Window
...
xmlns:bpy="clr-namespace:Basler.Pylon;assembly=Basler.Pylon"/>
...
<ComboBox Name="CamerasList" ItemsSource="{Binding CameraFound }" DisplayMemberPath="[bpy:CameraInfoKey.FriendlyName]" />

问题

但是绑定无法获取值(ItemsSource 不是问题,如果我删除 DisplayMemberPath,列表就会显示)

我不确定 XAML 中的 bpy 命名空间是否可以获取静态 属性 CameraInfoKey.FriendlyName,根据 documentation 是可能的将索引器与绑定一起使用,但我也不确定用法。

你知道错误可能来自哪里吗?

如果 ICameraInfo 没有您想要的 FriendlyName 属性 并且您必须从索引器 属性 中获取实际值,我不认为 DisplayMemberPath是你要走的路。相反,您可能应该为 ComboBox 布局 ItemTemplate,并在其中设置一个提取字符串值的 TextBlock。如有必要,您甚至可以为此使用转换器。例如,像这样:

// Takes an ICamerInfo value and a string parameter of the key and returns the result of the indexer

public class CameraInfoPropertyConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is not ICameraInfo info)
            return DependencyProperty.UnsetValue;

        if (parameter is not string key)
            return DependencyProperty.UnsetValue

        return info[key];
    }
}

然后,您的 ComboBox 使用 ItemTemplate 而不是 DisplayMemberPath 并依赖转换器从索引器

获取 属性
<ComboBox Name="CamerasList" ItemsSource="{Binding CameraFound }">
    <ComboBox.Resources>
        <MyNameSpace:CamerInfoPropertyConveter x:Key="InfoConverter"/>
    </ComboBox.Resources>

    <ComboBox.ItemTemplate>
        <DataTemplate DataType="{x:Type MyNameSpace:ICameraInfo}">
            <TextBlock Text="{Binding Converter={StaticResource InfoConverter}, 
                                      ConverterParameter="{x:Static bpy:CameraInfoKey.FriendlyName}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

请注意,我没有编译这个或任何东西。我假设 bpy:CameraInfoKey.FriendlyName 确实是一个静态可用的字符串值

Binding Path中方括号之间的部分不能是变量。当你写

DisplayMemberPath="[bpy:CameraInfoKey.FriendlyName]"

字符串 "bpy:CameraInfoKey.FriendlyName" 被传递给索引器 属性。

一个简单的解决方案可能是使用 XAML 中 CameraInfoKey.FriendlyName 属性 的

假设声明类似于

public class CameraInfoKey
{
    public static string FriendlyName { get; } = "friendly_name";
}

以下 XAML 可以工作:

DisplayMemberPath="[friendly_name]"