Как связать ComboBox со списком, который находится внутри ObservableCollection? - PullRequest
0 голосов
/ 08 мая 2019

Итак, у меня есть ObservableCollection типа AcquisitionDeviceInfo, который является пользовательским классом, этот пользовательский класс имеет свойство типа 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"/>

Вот что я получаю:

введите описание изображения здесь

и это то, что я ожидаю:

введите описание изображения здесь

заранее спасибо

Ответы [ 2 ]

0 голосов
/ 09 мая 2019

Чтобы сгладить 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 после добавления информационного элемента в наблюдаемый объект, эти значения не будут обновлены в пользовательском интерфейсе, поскольку список не наблюдается и не наблюдается , Кроме того, если у вас есть повторяющиеся имена устройств в нескольких информационных элементах, вы увидите странное поведение при удалении элементов из _observableAcquisitionDevices.

0 голосов
/ 08 мая 2019

Вам нужно изменить ваш ItemSource

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