2011-02-14 130 views
6

我想在按下回车键时让WPF AutoCompleteBox引发KeyDown事件。我正在使用普通的KeyDown钩子,它似乎适用于除了输入键之外的所有东西。有谁知道我该如何解决这个问题?WPF自动完成框和输入键

+0

当您按下Enter键时,您希望它做什么? – Jay 2011-02-14 20:21:57

+0

??我想让它赶上事件! – 2011-02-14 20:30:33

+0

你试过PreviewKeyDown了吗? – Ragepotato 2011-02-14 20:42:10

回答

10

您可以继承AutoCompleteBox,为添加事件输入

public class MyAutoCompleteBox : AutoCompleteBox 
{ 
    public override void OnKeyDown(KeyEventArgs e) 
    { 
     base.OnKeyDown(e); 
     if(e.Key == Key.Enter) RaiseEnterKeyDownEvent(); 
    } 

    public event Action<object> EnterKeyDown; 
    private void RaiseEnterKeyDownEvent() 
    { 
     var handler = EnterKeyDown; 
     if(handler != null) handler(this); 
    } 
} 

在你的消费类,你可以订阅:

public void Subscribe() 
{ 
    autoCompleteBox.EnterKeyDown += DoSomethingWhenEnterPressed; 
} 

public void DoSomethingWhenEnterPressed(object sender) 
{ 

} 
4

一个稍微容易(在我看来更MVVM)方式:

// This still goes in your code behind (yuck!) 
protected override void OnKeyDown(KeyEventArgs e) 
     { 
      if (!IsDropDownOpen && SelectedItem != null && (e.Key == Key.Enter || e.Key == Key.Return)) 
      { 
       // Drop down is closed so the item in the textbox should be submitted with a press of the Enter key 
       base.OnKeyDown(e); // This has to happen before we mark Handled = false 
       e.Handled = false; // Set Handled = false so the event bubbles up to your inputbindings 
       return; 
      } 

      // Drop down is open so user must be selecting an AutoComplete list item 
      base.OnKeyDown(e); 
     } 

这最小化亵渎code-behind,并允许您的关键事件继续冒泡像输入绑定:

<UserControl.InputBindings> 
    <KeyBinding Key="Tab" Command="{Binding NextCommand}"/> 
    <KeyBinding Key="Tab" Modifiers="Shift" Command="{Binding LastCommand}"/> 
    <KeyBinding Key="Escape" Command="{Binding ClearCommand}"/> 
    <KeyBinding Key="Enter" Command="{Binding EnterCommand}"/> 
</UserControl.InputBindings> 
-1

另外,使用Caliburn Micro时,你可以简单地使用:

<Controls:AutoCompleteBox ItemsSource="{Binding Keywords}" 
          ValueMemberPath="Name"     
          Text="{Binding EnteredText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
          IsTextCompletionEnabled="True" 
          cal:Message.Attach="[Event PreviewKeyDown] = [Action AddTagOnEnter($eventArgs)]" /> 

特别要注意最后一行附上您的活动。有关其他方法参数选项,请参见here

最后,定义你的视图模型的公共方法:

public void AddTagOnEnter(KeyEventArgs e) 
{ 
    if (e.Key != Key.Enter) return; 
    // Do something useful 
} 
8

很晚了答案,但我面对的是把我带到了这个问题,这个同样的问题,终于解决了它使用PreviewKeyDown

<wpftoolkit:AutoCompleteBox Name="AutoCompleteBoxCardName" 
    Populating="LoadAutocomplete" 
    PreviewKeyDown="AutoCompleteBoxName_PreviewKeyDown"/> 

private void AutoCompleteBoxName_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Enter) 
    { 
     //... 
    } 
} 
1

(我知道这是一个迟到的答案,但我仍然认为它'小号有用谁想要解决这个问题,不落后代码)

一个好办法MVVM为此在

首先添加引用人:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 

,并从NuGet包装(MVVMLight):

xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras" 

比你的查看

<wpftoolkit:AutoCompleteBox Name="AutoCompleteBoxName"> 
    <i:Interaction.Triggers> 
        <i:EventTrigger EventName="PreviewKeyDown"> 
         <cmd:EventToCommand Command="{Binding AutoCompleteEnter}" PassEventArgsToCommand="True"/> 
        </i:EventTrigger> 
       </i:Interaction.Triggers> 
</wpftoolkit:AutoCompleteBox> 
视图模型

比:

public ICommand AutoCompleteEnter { get { return new RelayCommand<System.Windows.Input.KeyEventArgs>(Auto_Complete_Enter); } } 

public void Auto_Complete_Enter(System.Windows.Input.KeyEventArgs e) 
{ 
    //Detect if key is 'Enter/Return' key 
    if ((e.Key == Key.Enter) || (e.Key == Key.Return)) 
    { 
     Console.WriteLine("U have pressed the enter key"); 
    } 
} 

希望这仍然会帮助一些人出来。