WPF自定义控件问题(Multi-Select Combobox)

时间:2011-03-15 13:23:47

标签: c# .net wpf xaml user-controls

在代码项目中,我发现了以下内容: http://www.codeproject.com/KB/WPF/MultiComboBox.aspx

我已将以下内容集成到示例应用程序中,似乎运行良好。我现在唯一的问题是,如果我输入控件,我希望以与正常组合框或列表框功能相同的方式使用以这些字母开头的项目。

我尝试添加KeyboardNavigation.DirectionalNavigation="Contained"TextSearch.TextPath="City"以及IsTextSearchEnabled="True"

这些似乎都没有帮助。有关如何使用此控件实现文本搜索功能的任何想法?

1 个答案:

答案 0 :(得分:1)

作者确认该控件是为了模仿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);
    }

你应该让关键分析比矿井更好,但道路很晴朗。 注意:我没有尝试过这么多测试,我想应该没问题,至少可以给你一个帮助。 干杯 马里奥

EDIT2:这是如何在一秒钟内跟踪按下的键。 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;

希望它有所帮助。 干杯 马里奥