Несколько ComboBox связаны с общим источником, обеспечивая различные выборки - PullRequest
4 голосов
/ 21 апреля 2011

Я пытаюсь связать несколько ComboBox с общей коллекцией источников и обеспечить, чтобы после выбора ComboBox выбранный элемент удалялся из другого ComboBox как возможность.Коллекция создается динамически, поэтому я делаю это в коде.

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

Я пытался использовать предикат фильтра представления по умолчанию, но он только пропускает элемент, и у меня нет способа узнать, какой элемент управления выполняет фильтр (и это даже не имеет смысла концептуально).

Я пытался создать новый CollectionView, но в итоге поведение было другим (получение событий SelectionChange, которых раньше не было с представлением по умолчанию).

Я бился головой об этомчасов, и он просто не хочет работать.Я был бы признателен, если бы кто-то более опытный с WPF помог мне с рабочим примером.Мне бы очень хотелось, чтобы он не выбирал элементы из коллекции автоматически и начинал с пустого места (в противном случае каждый ComboBox будет иметь отдельный автоматический выбор, который слишком самонадеян).Широкий выбор и проверка позже, но это кажется такой простой концепцией, с такой невероятной трудностью.

Спасибо

Ответы [ 2 ]

3 голосов
/ 21 апреля 2011

Хороший вопрос, я думал об этом, и я, вероятно, подхожу к нему с помощью MultiBinding и соответствующего ValueConverter, т.е.

<StackPanel>
    <StackPanel.Resources>
        <local:ComboBoxItemsSourceFilter x:Key="ComboBoxItemsSourceFilter"/>
    </StackPanel.Resources>
    <ComboBox Name="cb1">
        <ComboBox.ItemsSource>
            <MultiBinding Converter="{StaticResource ComboBoxItemsSourceFilter}">
                <Binding Path="Emps"/> <!-- Source collection binding -->
                <Binding ElementName="cb2" Path="SelectedItem"/>
                <Binding ElementName="cb3" Path="SelectedItem"/>
            </MultiBinding>
        </ComboBox.ItemsSource>
    </ComboBox>
    <ComboBox Name="cb2">
        <ComboBox.ItemsSource>
            <MultiBinding Converter="{StaticResource ComboBoxItemsSourceFilter}">
                <Binding Path="Emps"/>
                <Binding ElementName="cb1" Path="SelectedItem"/>
                <Binding ElementName="cb3" Path="SelectedItem"/>
            </MultiBinding>
        </ComboBox.ItemsSource>
    </ComboBox>
    <ComboBox Name="cb3">
        <ComboBox.ItemsSource>
            <MultiBinding Converter="{StaticResource ComboBoxItemsSourceFilter}">
                <Binding Path="Emps"/>
                <Binding ElementName="cb1" Path="SelectedItem"/>
                <Binding ElementName="cb2" Path="SelectedItem"/>
            </MultiBinding>
        </ComboBox.ItemsSource>
    </ComboBox>
</StackPanel>
public class ComboBoxItemsSourceFilter : IMultiValueConverter
{
    #region IMultiValueConverter Members

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var collection = new List<object>((object[])values[0]);
        foreach (var item in values.Skip(1))
        {
            if (item != null) collection.Remove(item);
        }
        return collection;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    #endregion
}

Поскольку вы делаете это в коде, добавляющем все эти привязки, не должно быть большой проблемой, просто бросьте все комбинированные списки в список, и вы можете их перебирать. Преобразователю может потребоваться некоторая настройка, поскольку предполагается, что набор входных данных (values[0]) может быть приведен к object[].

Этот способ, к сожалению, вызывает множество исключений из первого шанса, причину которых я до сих пор не могу определить ...

Первое случайное исключение типа 'System.Runtime.InteropServices.COMException' произошло в UIAutomationProvider.dll

1 голос
/ 24 апреля 2011

Я не совсем уверен, что я сделал неправильно в первый раз, однако я изменил несколько вещей и получил свою первоначальную попытку.

Возможно, проблемы, с которыми я столкнулся, были результатомиспользования CollectionView напрямую, о чем есть предупреждение в выводе отладки.В нем говорится, что использование CollectionView напрямую не полностью поддерживается и может иметь некорректное поведение.

В итоге я переключился на ListCollectionView.Я также создал новый List <>, содержащий содержимое моей исходной коллекции, что позволило мне добавить пустой список в список (без изменения исходной структуры данных).Я просто игнорирую это при изменении выбора и безоговорочно включаю его в фильтр.

Итак, шаги, чтобы заставить его работать:
1) ListCollectionView с исходным кодом IList
2) Добавить предикат фильтра в представление
3) Создать привязку с представлением в качестве источника
4) combo.SetBinding для ComboBox.ItemsSource
5) При изменении события выбора, обязательно приведите ItemsSource каждой комбинации в ICollectionView и вызовите Refresh (так как для этого потребуетсяперефильтровать, а уведомления об изменении свойства не замечены)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...