Проблема с пользовательским элементом управления WPF (Multi-Select Combobox) - PullRequest
2 голосов
/ 15 марта 2011

В проекте кода я обнаружил следующее: http://www.codeproject.com/KB/WPF/MultiComboBox.aspx

Я включил следующее в пример приложения, и оно, кажется, работает хорошо.Единственная проблема, с которой я столкнулся на данный момент, заключается в том, что если я введу элемент управления, я бы хотел, чтобы его перенаправили на элементы, начинающиеся с этих букв, так же, как обычные функции комбинированного списка или списка.1006 * и TextSearch.TextPath="City", а также IsTextSearchEnabled="True".

Кажется, что ничего из этого не помогает.Есть мысли о том, как реализовать функцию текстового поиска с помощью этого элемента управления?

1 Ответ

1 голос
/ 15 марта 2011

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

РЕДАКТИРОВАТЬ (иначе даже лучше, чем палец)в глаза)

С учетом исходного кода: 1) В Generic.xaml найдите MultiSelectComboBoxReadOnlyTemplate, затем найдите тег ScrollViewer: назовите его «PART_Scroller».

2) Откройте модуль MultiComboBox.cs и найдите функцию OnKeyDown.Изменить следующим образом:

    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (e.Key == System.Windows.Input.Key.Enter)
        {
            IsDropDownOpen = !IsDropDownOpen;
            e.Handled = true;
        }
        else if (IsDropDownOpen)
        {
            if (e.Key>=Key.A && e.Key<= Key.Z) //make it better!
            {
                var ch = (char)((int)(e.Key-Key.A) + 0x41); //awful!!!
                for (int i = 0, count = this.Items.Count; i < count; i++)
                {
                    var text = string.Format("{0}", this.Items[i]);
                    if (text.StartsWith(new string(ch, 1)))
                    {
                        ListBoxItem listBoxItem = (ListBoxItem)this.ItemContainerGenerator.ContainerFromIndex(i);
                        var scroller = (ScrollViewer)this.GetTemplateChild("PART_Scroller"); //move out in OnApplyTemplate
                        scroller.ScrollToVerticalOffset(i);
                        this.ScrollIntoView(listBoxItem);
                        break;
                    }
                }

            }
        }
        else
            base.OnKeyDown(e);
    }

Вы должны сделать анализ ключа лучше, чем мой, но дорога довольно солнечная.ПРИМЕЧАНИЕ: я не так много пытался проверить, я думаю, все должно быть в порядке, по крайней мере, чтобы помочь вам.Приветствия Марио

РЕДАКТИРОВАТЬ2: вот как отслеживать нажатие клавиши в течение одной секунды.1) Изменить следующим образом:

    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (e.Key == System.Windows.Input.Key.Enter)
        {
            IsDropDownOpen = !IsDropDownOpen;
            e.Handled = true;
        }
        else if (IsDropDownOpen)
        {
            if (e.Key>=Key.A && e.Key<= Key.Z) //make it better!
            {
                var ch = (char)((int)(e.Key-Key.A) + 0x41); //awful!!!
                this._textSought += ch;
                this._timer.Stop();
                this._timer.Start();

                for (int i = 0, count = this.Items.Count; i < count; i++)
                {
                    var text = string.Format("{0}", this.Items[i]);
                    if (text.StartsWith(this._textSought, StringComparison.InvariantCultureIgnoreCase))
                    {
                        ListBoxItem listBoxItem = (ListBoxItem)this.ItemContainerGenerator.ContainerFromIndex(i);
                        var scroller = (ScrollViewer)this.GetTemplateChild("PART_Scroller"); //move out in OnApplyTemplate
                        scroller.ScrollToVerticalOffset(i);
                        this.ScrollIntoView(listBoxItem);
                        break;
                    }
                }

            }
        }
        else
            base.OnKeyDown(e);
    }

2) добавить к тому же классу следующее:

    public MultiComboBox()
    {
        this.Loaded += new RoutedEventHandler(MultiComboBox_Loaded);
        this.Unloaded += new RoutedEventHandler(MultiComboBox_Unloaded);
    }

    void MultiComboBox_Loaded(object sender, RoutedEventArgs e)
    {
        this._timer = new DispatcherTimer();
        this._timer.Interval = TimeSpan.FromMilliseconds(1000);
        this._timer.Tick += new EventHandler(_timer_Tick);
    }

    void MultiComboBox_Unloaded(object sender, RoutedEventArgs e)
    {
        if (this._timer != null)
        {
            this._timer.Stop();
            this._timer = null;
        }
    }

    void _timer_Tick(object sender, EventArgs e)
    {
        this._timer.Stop();
        this._textSought = string.Empty;
    }

    private DispatcherTimer _timer;
    private string _textSought = string.Empty;

Надеюсь, это поможет.Ура Марио

...