如何在WPF中使用列表的值动态填充带有XAML的ComboBox?

时间:2018-12-12 16:23:41

标签: wpf list xaml combobox

在CSV文件中,我有一些用';'分隔的字符串值和一些列表(以“,”分隔的值)。阅读CSV后,我想将列表显示为组合框。 如何使用WPF / XAML做到这一点?

我尝试过:

<ComboBoxItem>
    <StackPanel Orientation="Horizontal">
        <TextBlock Name="DetailParams" Text="{Binding Path=DetailParams, Converter={StaticResource StringListConverter}}" />
    </StackPanel>
</ComboBoxItem>

...但是这会生成一个组合框项目“(集合)”(德语:“(Sammlung”)

更准确地说: 组合框应显示在DataGrid的每一行列中,其中每一行都显示一个 XYZ 类的实体。 ComboBox的值确实来自其他地方,但不是来自 XYZ 。无论如何:ComboBox的选定值最终应存储在 XYZ 的属性中(并且在显示DataGrid / ComboBox时,应在ComboBox中预先选择项目)。

MainWindow.cs:
private List<string> _tagNames = new List<string>();
public IList<string> TagNames { get { return _tagNames; } }

<Window.Resources>
    <CollectionViewSource x:Key="NotificationsCollectionViewSource" CollectionViewType="ListCollectionView"/>
    <lb:StringListConverter x:Key="StringListConverter" />
</Window.Resources>

<DataGrid x:Name="notificationsGrid" DataContext="{StaticResource NotificationsCollectionViewSource}" ItemsSource="{Binding}" 
AlternatingRowBackground="LightBlue" AutoGenerateColumns="False" CanUserAddRows="True" IsReadOnly="False" 
SelectionMode="Single">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Tag name" Binding="{Binding Mode=TwoWay, Path=TagName}"></DataGridTextColumn>
        <DataGridTextColumn Header="NId" Binding="{Binding Mode=TwoWay, Path=Nid}"></DataGridTextColumn>
        <DataGridCheckBoxColumn Header="IsActive" Binding="{Binding Mode=TwoWay, Path=IsActive}"></DataGridCheckBoxColumn>
        <DataGridTemplateColumn x:Name="detailsParamColumn" Header="Edit">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding Path=TagNames, Converter={StaticResource StringListConverter}}">
                    </ComboBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

StringListConverter.cs:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Data;

namespace ConfigTool.DataBinding
{
    public class StringListConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value.ToString().Split(',').ToList();
        }

        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            StringBuilder sb = new StringBuilder();
            List<string> items = value as List<string>;
            for( int i=0; i<items.Count; i++ )
            {
                sb.Append(items[i].Trim());
                if( i<items.Count-1 )
                {
                    sb.Append(",");
                }
            }
            return sb.ToString();
        }
    }
}

因为我想将选定的值写回CSV文件: 绑定模式应该为 TwoWay 吗?

更新:

在通知的DataGrid中,我想要一个ComboBox,其中的标签名称所有可能的值。这些标签名称位于MainWindow.cs的List 中,但是此列表(名为 _tagNames )既不是NotificationViewSource的一部分,也不是基础Notification类的一部分。通知可能分配了一个或多个标签名称,但在组合框中所有可能的标签名称(来自属性 _tagNames )应显示并可以选择。 ...并且所选项目的列表将在以后写回。 因为 _tagNames 只是一个字符串列表,所以我无法设置诸如 Binding Path = whatever ...

更新(2018-12-14):

再说一次(因为也许我的英语不太好,以至于我对任何意图都没有足够的解释;-)):我有一个通知类

pulic class Notification
{
    public List<string> _mySelectedTagNames { get; set; }
}

在MainWindow.cs中:

public partial cass MainWindow : Window
{
    private List<string> _tagNames; // initialized with maybe 100 tagNames (all possible values from which a subset (or even all) can be selected and hence stored in `Notification.mySelectedTagnames`)
}

MainWindow._tagNames将显示在组合框中,该组合框显示在每一行的一列中。 用户可以选择零个或多个项目,这些选择的项目应存储在Notification类的基础行中。

1 个答案:

答案 0 :(得分:0)

ItemsSource的{​​{1}}属性设置(或绑定)到字符串列表:

ComboBox

这应该给您一个<ComboBox ItemsSource="{Binding Path=DetailParams, Converter={StaticResource StringListConverter}}" /> ,并在转换器返回的列表中每个条目都有一个项目。

如果要在水平ComboBox中相邻显示项目,可以使用StackPanel

ItemsControl