.net WPF转换器,用于与静态项目组合的可观察采集

.net WPF转换器,用于与静态项目组合的可观察采集,.net,wpf,observablecollection,ivalueconverter,.net,Wpf,Observablecollection,Ivalueconverter,我正在尝试将组合框绑定到一个可观察集合,该集合将有一些静态项作为第一个项,然后是集合中的实际项 No index 1% p.a. 5% p.a. -------- Item1 Item2 Item3 我认为绑定转换器可以做到这一点 <ComboBox ItemsSource = "{Binding indexes}, Converter={StaticResource IndexCollectionConverter}}" /> 如何定义转换器以返回集合?尝试IMultiValu

我正在尝试将组合框绑定到一个
可观察集合
,该集合将有一些静态项作为第一个项,然后是集合中的实际项

No index
1% p.a.
5% p.a.
--------
Item1
Item2
Item3
我认为绑定转换器可以做到这一点

<ComboBox ItemsSource = "{Binding indexes}, Converter={StaticResource IndexCollectionConverter}}" />

如何定义转换器以返回集合?

尝试IMultiValueConverter:

public class IndexCollectionConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return values                               // loop through all values
            .Select(v => v as IEnumerable<object>)  // cast to something we can enumerate
            .Where(v => v != null)                  // ignore anything we can't
            .SelectMany(v => v)                     // concat them all into a single list
            .ToList();                              // turn into a memory array now
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
公共类IndexCollectionConverter:IMultiValueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,System.Globalization.CultureInfo区域性)
{
返回值//遍历所有值
.Select(v=>v as IEnumerable)//转换为我们可以枚举的内容
.Where(v=>v!=null)//忽略任何我们不能忽略的内容
.SelectMany(v=>v)//将它们全部合并到一个列表中
.ToList();//立即转换为内存数组
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,System.Globalization.CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
下面是一些示例代码,我使用XmlDataProviders只是为了说明它的工作原理,但您可以将源绑定更改为任何内容:

<Window.Resources>

    <local:IndexCollectionConverter x:Key="IndexCollectionConverter" />

    <XmlDataProvider x:Key="StaticIndexes">
        <x:XData>
            <IndexData xmlns="">
                <Item Desc="No Index" />
                <Item Desc="1% p.a." />
                <Item Desc="2% p.a." />
            </IndexData>
        </x:XData>
    </XmlDataProvider>

    <XmlDataProvider x:Key="DynamicIndexes">
        <x:XData>
            <IndexData xmlns="">
                <Item Desc="Item1" />
                <Item Desc="Item2" />
                <Item Desc="Item3" />
            </IndexData>
        </x:XData>
    </XmlDataProvider>

</Window.Resources>

<ComboBox VerticalAlignment="Top" IsDropDownOpen="True">
    <ComboBox.ItemsSource>
        <MultiBinding Converter="{StaticResource IndexCollectionConverter}">
            <Binding Source="{StaticResource StaticIndexes}" XPath="IndexData/Item" />
            <Binding Source="{StaticResource DynamicIndexes}" XPath="IndexData/Item" />
        </MultiBinding>
    </ComboBox.ItemsSource>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding XPath=@Desc}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

结果:


为什么不在代码中填充静态项?创建indexes ObservableCollection,用静态项填充它,然后添加运行时加载的项。
public class IndexCollectionConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return values                               // loop through all values
            .Select(v => v as IEnumerable<object>)  // cast to something we can enumerate
            .Where(v => v != null)                  // ignore anything we can't
            .SelectMany(v => v)                     // concat them all into a single list
            .ToList();                              // turn into a memory array now
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
<Window.Resources>

    <local:IndexCollectionConverter x:Key="IndexCollectionConverter" />

    <XmlDataProvider x:Key="StaticIndexes">
        <x:XData>
            <IndexData xmlns="">
                <Item Desc="No Index" />
                <Item Desc="1% p.a." />
                <Item Desc="2% p.a." />
            </IndexData>
        </x:XData>
    </XmlDataProvider>

    <XmlDataProvider x:Key="DynamicIndexes">
        <x:XData>
            <IndexData xmlns="">
                <Item Desc="Item1" />
                <Item Desc="Item2" />
                <Item Desc="Item3" />
            </IndexData>
        </x:XData>
    </XmlDataProvider>

</Window.Resources>

<ComboBox VerticalAlignment="Top" IsDropDownOpen="True">
    <ComboBox.ItemsSource>
        <MultiBinding Converter="{StaticResource IndexCollectionConverter}">
            <Binding Source="{StaticResource StaticIndexes}" XPath="IndexData/Item" />
            <Binding Source="{StaticResource DynamicIndexes}" XPath="IndexData/Item" />
        </MultiBinding>
    </ComboBox.ItemsSource>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding XPath=@Desc}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>