如何将ComboBox绑定到ObservableCollection内部的列表?

时间:2019-05-08 01:41:37

标签: c# wpf combobox observablecollection

所以我有一个类型为AcquisitionDeviceInfo的ObservableCollection,它是一个自定义类,该自定义类具有类型List<string>的属性,我想在组合框中显示此列表的内容,并且我希望能够捕获选定的项目,但我不知道如何正确执行。

我试图将组合框绑定到我的可观察集合,并将DisplayMemberPath属性设置为我的列表,但是它不起作用。

编辑1:我已将代码更改为MVCE,因此你们可以更轻松地了解我要执行的操作。

这是我的AcquisitionDeviceInfo类。

public class AcquisitionDeviceInfo
    {
        private List<string> _device;

        public AcquisitionDeviceInfo()
        {
            _device = new List<string>();
        }

        public List<string> Device { get => _device; set => _device = value; }
    }

这是我后面的代码:

public partial class MainWindow : Window
    {
        private ObservableCollection<AcquisitionDeviceInfo> _observableAcquisitionDevices;

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;

            _observableAcquisitionDevices = new ObservableCollection<AcquisitionDeviceInfo>();

            AcquisitionDeviceInfo Info1 = new AcquisitionDeviceInfo { Device = { "A", "B", "C" } };
            AcquisitionDeviceInfo Info2 = new AcquisitionDeviceInfo { Device = { "D", "E", "F" } };
            AcquisitionDeviceInfo Info3 = new AcquisitionDeviceInfo { Device = { "G", "H", "I" } };

            ObservableAcquisitionDevices.Add(Info1);
            ObservableAcquisitionDevices.Add(Info2);
            ObservableAcquisitionDevices.Add(Info3);
        }

        public ObservableCollection<AcquisitionDeviceInfo> ObservableAcquisitionDevices { get => _observableAcquisitionDevices; set => _observableAcquisitionDevices = value; }
    }    

我的组合框xaml代码如下:

<ComboBox Name="cbboxDevices" Grid.Column="1" Margin="10"
         ItemsSource="{Binding Path=ObservableAcquisitionDevices}"
         DisplayMemberPath="Device"/>

这就是我得到的:

enter image description here

这就是我所期望的:

enter image description here

预先感谢

2 个答案:

答案 0 :(得分:0)

您需要修改ItemSource

 <ComboBox Name="cbboxDevices" Grid.Column="1" Margin="10"
         ItemsSource="{Binding Path=ObservableAcquisitionDevices[0].Device}"
        />

答案 1 :(得分:0)

要展平ObservableCollection<AcquisitionDeviceInfo>,您将需要观察该可观察集合的INotifyCollectionChanged.CollectionChanged事件,然后使用嵌套列表内容更新ObservableCollection<string>并将组合框绑定到字符串集合

private ObservableCollection<AcquisitionDeviceInfo> _observableAcquisitionDevices;
private ObservableCollection<string> ObservableDevices { get; private set; }

public MainWindow()
{
    InitializeComponent();

    ObservableDevices = new ObservableCollection<string>();
    _observableAcquisitionDevices = new ObservableCollection<AcquisitionDeviceInfo>();
    _observableAcquisitionDevices.CollectionChanged += AquisitionDevices_CollectionChanged;

    // set the data context after the property we are binding to is set
    // especially if you don't have property change support in place
    DataContext = this;

    // add data to _observableAcquisitionDevices
}

private void AquisitionDevices_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if ((e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Replace) && e.OldItems != null)
    {
        for each (var device in e.OldItems.OfType<AcquisitionDeviceInfo>().Device)
        {
            ObservableDevices.Remove(device);
        }
    }
    if ((e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Replace) && e.NewItems != null)
    {
        for each (var device in e.NewItems.OfType<AcquisitionDeviceInfo>().Device)
        {
            ObservableDevices.Add(device);
        }
    }
    if (e.Action == Reset)
    {
        ObservableDevices.Clear();
    }
}

并绑定到组合框:

<ComboBox Name="cbboxDevices" Grid.Column="1" Margin="10"
     ItemsSource="{Binding Path=ObservableDevices}"
    />

要注意的其他事项是,如果在将信息项添加到可观察项之后将任何字符串值添加到AcquisitionDeviceInfo.Device列表中,这些值将不会更新到UI中,因为该列表是不可观察的,并且没有观察到。另外,如果您在多个信息项上使用重复的设备名称,则从_observableAcquisitionDevices中删除项时会看到一些奇怪的行为。