2011-03-15 68 views
2

代码项目,我发现以下几点: http://www.codeproject.com/KB/WPF/MultiComboBox.aspx与WPF自定义控件(多选组合框)问题

我已经集成了以下内容一个示例应用程序,它似乎运作良好。我现在唯一的问题是,如果我输入控件,我想以这些字母开头的项目与正常的组合框或列表框的功能相同。

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

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

+0

vb.net和c#as标签? – 2011-03-15 15:44:19

+0

如果它只能在代码后面完成,那么是的。两种语言都可以,如果有必要我可以转换。如果它完全可以在XAML中完成,则更好。 – Matt 2011-03-15 15:55:49

回答

1

作者确认该控件的构建模仿了ComboBox,但它不是:您应该将自己的自定义逻辑实现为自动选择。

EDIT(又名甚至比眼睛手指更好)

参照原代码: 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; 

希望它能帮助。 干杯 马里奥

+0

这正是我所坚持的......因此,问题 – Matt 2011-03-15 14:55:50

+0

让我很好理解:一旦列表下降,您将按下一个键,以便列表滚动到以该字母开头的最近的项目?或者,你要求一个更时髦的组合,过滤器(然后显示你)只有包含该字母的项目? – 2011-03-15 15:50:31

+0

按一个键,并滚动列表到最近的那个字母开头 – Matt 2011-03-15 15:56:10