Добавление элемента в коллекцию ObservableCollection неизвестного типа - PullRequest
1 голос
/ 11 января 2010

Я создаю приложение WPF с использованием шаблона проектирования MVVM и пытаюсь создать Combobox, который позволяет пользователю редактировать элементы в раскрывающемся списке во время выполнения, подобно тому, как MS Access 2007 позволяет ты делаешь это. Итак, я создал UserControl, который строится поверх Combobox ... когда отображается выпадающий список, под списком есть кнопка, которая открывает другое окно для редактирования элементов в списке. Довольно просто, но всплывающее окно ничего не знает о типе элементов в списке, за исключением того, что они имеют некоторый тип ObservableCollection.

Вы можете просмотреть скриншот того, что я пытаюсь объяснить ЗДЕСЬ .

Например, в представлении я привязываю пользовательский комбинированный список к ObservableCollection<Sizes>. Я нажимаю кнопку, чтобы редактировать список, и во всплывающем окне отображаются все элементы в текстовом поле, которые пользователь может редактировать. Проблема заключается в попытке добавить / обновить / удалить элементы в ObservableCollection из всплывающего окна. Это окно не знает ничего о ObservableCollection, кроме имени поля отображения (this.DisplayMemberPath).

Я знаю, что всегда могу связать комбинированный список с ObservableCollection<string> или IEnumerable<string>, но я использую LINQ to SQL для заполнения элементов комбинированного списка, и мне нужно знать об отслеживании изменений на всех моих объектах так что я могу обновить базу данных изменений, внесенных в список. Поэтому (я думаю) я должен использовать ObservableCollection<Sizes>, чтобы отслеживать отслеживание изменений. Мне также понравилась идея использовать событие CollectionChanged для обновления базы данных, но мне интересно, есть ли более чистый метод.

У меня есть ощущение, что мне понадобится использовать Reflection для обновления списка, но я не очень хорошо разбираюсь в работе с Reflection.

Вот мой исходный код для отображения всплывающего окна:

public event EventHandler<EventArgs> EditListClick;
private void EditButton_Click(object sender, RoutedEventArgs e)
{
    if (this.EditListDialog == null)
    {
        // Create the default dialog window for editing the list
        EditListDialogWindow dialog = new EditListDialogWindow();
        string items = string.Empty;

        if (this.Items != null)
        {
            // Loop through each item and flatten the list
            foreach (object item in this.Items)
            {
                PropertyInfo pi = item.GetType().GetProperty(this.DisplayMemberPath);
                string value = pi.GetValue(item, null) as string;

                items = string.Concat(items, ((items == string.Empty) ? items : "\n") + value);
            }

            // Now pass the information to the dialog window
            dialog.TextList = items;
        }

        // Set the owner and display the dialog
        dialog.Owner = Window.GetWindow(this);
        dialog.ShowDialog();

        // If the user has pressed the OK button...
        if (dialog.DialogResult.HasValue && dialog.DialogResult.Value)
        {
            // Make sure there has been a change
            if (items != dialog.TextList)
            {
                // Unflatten the string into an Array
                string[] itemArray = dialog.TextList.Split(new string[]{"\n", "\r"}, StringSplitOptions.RemoveEmptyEntries);

                // Add the items to the list
                foreach (string item in itemArray)
                {
                    // This is where I run into problems...
                    // Should I be using reflection here??
                    ((ObservableCollection<object>)this.ItemsSource).Add(item.Trim());
                }
            }
        }
    }

    if (EditListClick != null)
        EditListClick(this, EventArgs.Empty);
}

Ответы [ 2 ]

2 голосов
/ 11 января 2010

Похоже, вам нужно знать о списке, но не о конкретных типах. Вот где вступают неуниверсальные интерфейсы; попробуйте получить доступ к списку как IList (в котором есть все индексаторы / Добавить / Удалить и т. д.), INotifyCollectionChanged (для уведомлений) и т. д.

В более общем случае также есть IBindingList / IBindingListView / ITypedList и т. Д., Но я не думаю, что они вам понадобятся в этом случае.

0 голосов
/ 11 января 2010

Вы пытались использовать IValueConverter ?

Когда вы связываете ObservbleCollection с пользовательским ComboBox, установите пользовательский IValueConverter. Его определяет 2 метода, Convert и ConvertBack. Идея в том, что вы можете конвертировать типы.

В этом случае у вас может быть ObservableCollection<Sizes>, и конвертер привязок возьмет его и преобразует в требуемый тип.

Если вы установите конвертер для привязки коллекции, вы можете конвертировать в ObservableCollection<Sizes> и ObservableCollection<string>.

.

Другой вариант - установить внутри IValueConverter пользовательский ComboBox и выполнить преобразование из Sizes в string. Другой вариант, в сочетании с определенным элементом шаблона, содержит привязку и преобразование.

HtH.

...