【问题标题】:How can I dynamically fill a ComboBox with XAML in WPF with the values of a List?如何在 WPF 中使用 List 的值动态填充带有 XAML 的 ComboBox?
【发布时间】:2018-12-12 16:23:40
【问题描述】:

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

我试过这个:

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

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

更准确地说: ComboBox 应显示在 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 中,我希望有一个带有 所有可能值 的组合框作为标签名称。这些标签名称在我的 MainWindow.cs 的 List 中,但这个 list(名为 _tagNames)既不是 NotificationViewSource 的一部分,也不是基础 Notification 类的一部分。通知可能分配有一个或多个标签名称,但在组合框中所有可能的标签名称(来自属性_tagNames)应显示并能够选择。 ...稍后将写回所选项目的列表。 因为 _tagNames 只是一个字符串列表,所以我无法设置 Binding Path=whatever...

更新(2018-12-14):

再一次(因为也许我的英语不太好,以至于我已经足够好地解释了 ny intentiin 是什么 ;-)):我有一个类 Notification

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 应显示在 ComboBox 中,该 ComboBox 显示在每行的一列中。 用户可以选择零个、一个或多个项目,这些选定的项目应存储在 Notification 类的基础行中。

【问题讨论】:

  • ComboBoxItemsSource 设置为字符串列表? &lt;ComboBox ItemsSource="{Binding Path=DetailParams, Converter={StaticResource StringListConverter}}" /&gt;
  • 我相信 TagNames 必须是 String public string TagNames { get { return "A;B;C;D,E,F;G,I"; } } 的属性我的理解正确吗?
  • 没有。 TagNames 是一个包含所有可能值的字符串列表(可能有 100 个)。网格中的一行应显示一个对象,该对象具有一个字符串列表,该属性是包含 0..TagNames.length 列表 TagNames 项的字符串列表。

标签: wpf list xaml combobox


【解决方案1】:

ComboBoxItemsSource 属性设置(或绑定)到字符串列表:

<ComboBox ItemsSource="{Binding Path=DetailParams, Converter={StaticResource StringListConverter}}" />

这应该会给你一个ComboBox,在转换器返回的列表中每个条目都有一个项目。

如果您想在水平的StackPanel 中显示彼此相邻的项目,您可以使用ItemsControl

<ItemsControl ItemsSource="{Binding Path=DetailParams, Converter={StaticResource StringListConverter}}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock>
                <Run Text="{Binding Path=., Mode=OneWay}" />
                <Run Text=" " />
            </TextBlock>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

【讨论】:

    猜你喜欢
    • 2012-11-10
    • 2016-03-18
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 2019-03-23
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    相关资源
    最近更新 更多