2016-11-18 100 views
0

我有一个WPF XAML屏幕有多个控件(文本框,组合框,按钮等)。后面的代码是用C#编写的。我为其中一个按钮保留了IsDefault="True"。因此,如果用户在任何文本框中按输入键,表单将被提交。防止WPF窗体按Enter键提交

我需要提交表格使用输入键只为一个特定的文本框。如果用户按下在任何其他文本框中输入键,我不希望表单被提交。

我知道我可以用后面的代码来实现这个(即*.xaml.cs)。但是,如何使用MVVM设计模式来实现这一点?

+0

创建附加的行为,将连接相应的键事件来处理输入密钥。 –

+1

嗯,这是代码隐藏的工作,因为这是视图逻辑。 – Dennis

回答

1

只需在要处理的文本框上设置AcceptsReturn="True"即可自行输入,而不是路由到表单。

+0

这可行,但将文本框变成多行文本框。有什么办法可以防止这种情况发生? – Zack

+0

不像我在Windows 8/10上看到MaxLines属性无法正常工作那么远。我认为你可能不得不通过一个键盘事件处理程序来获取派生的控件,从而吞下按键。 –

2

你可能不在乎用户按下哪个文本框输入,你只是想要完成整个表单。如果是这种情况,请执行验证并使用绑定禁用按钮。

public ICommand SaveCommand 
{ 
    get 
    { 
     if (_saveCommand == null) 
      _saveCommand = new RelayCommand(x => Save(), CanSave); 

     return _saveCommand; 
    } 
} 

private void CanSave(object sender) 
{ 
    // Validate properties, ensure viewmodel is in savable state. 

    // Maybe you implemented IDataErrorInfo? 
    if (Validator.TryValidateObject(this, new ValidationContext(this, null, null), new List<ValidationResult>(), true)) 
     return true; 
    else 
     return false; 
} 

private void Save() 
{ 
    // Database stuff, maybe WCF stuff, etc. 
} 
+0

感谢FrumRoll的评论。但正如我所提到的,我只需要在用户按下一个特定的文本框中输入时提交表单(可以说txtboxProductKey)。不管用户是否输入了任何其他文本框,都不会触发表单提交txtboxProductKey中的值。 –

+1

@Vineetv你当然可以验证所有的绑定值,而不仅仅是ProductKey。但是,如果您只想使用单个文本框来触发该命令,则会从按钮中删除IsDefault =“True”,并将该命令绑定到文本框。 –

0

您可以从您的按钮中删除IsDefault =“True”,并将您的命令绑定到文本框本身。有很多方法可以在StackOverflow上执行此操作。我的首选是使用自定义文本框。

public class CommandTextBox : TextBox, ICommandSource 
{ 
    private bool _canExecute; 
    private EventHandler _canExecuteChanged; 

    protected override bool IsEnabledCore 
    { 
     get 
     { 
      if (Command != null) 
       return base.IsEnabledCore && _canExecute; 

      return base.IsEnabledCore; 
     } 
    } 

    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(CommandTextBox), new PropertyMetadata(OnCommandChanged)); 

    public ICommand Command 
    { 
     get { return (ICommand)GetValue(CommandProperty); } 
     set { SetValue(CommandProperty, value); } 
    } 

    public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(CommandTextBox)); 

    public object CommandParameter 
    { 
     get { return GetValue(CommandParameterProperty); } 
     set { SetValue(CommandParameterProperty, value); } 
    } 

    public static readonly DependencyProperty CommandTargetProperty = DependencyProperty.Register("CommandTarget", typeof(IInputElement), typeof(CommandTextBox)); 

    public IInputElement CommandTarget 
    { 
     get { return (IInputElement)GetValue(CommandTargetProperty); } 
     set { SetValue(CommandTargetProperty, value); } 
    } 

    protected override void OnPreviewKeyDown(KeyEventArgs e) 
    { 
     base.OnPreviewKeyDown(e); 

     if (e.Key == Key.Enter) 
     { 
      if (Command != null) 
      { 
       RoutedCommand command = Command as RoutedCommand; 

       if (command != null) 
        command.Execute(CommandParameter, CommandTarget); 
       else 
        Command.Execute(CommandParameter); 
      } 

      e.Handled = true; 
     } 
    } 

    private void AddCommand(ICommand command) 
    { 
     var handler = new EventHandler(CanExecuteChanged); 
     _canExecuteChanged = handler; 
     if (command != null) 
      command.CanExecuteChanged += _canExecuteChanged; 
    } 

    private void CanExecuteChanged(object sender, EventArgs e) 
    { 
     if (Command != null) 
     { 
      RoutedCommand command = Command as RoutedCommand; 

      // If a RoutedCommand. 
      if (command != null) 
       _canExecute = command.CanExecute(CommandParameter, CommandTarget); 
      else 
       _canExecute = Command.CanExecute(CommandParameter); 
     } 

     CoerceValue(UIElement.IsEnabledProperty); 
    } 

    private void HookUpCommand(ICommand oldCommand, ICommand newCommand) 
    { 
     // If oldCommand is not null, then we need to remove the handlers. 
     if (oldCommand != null) 
      RemoveCommand(oldCommand); 

     AddCommand(newCommand); 
    } 

    private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     ((CommandTextBox)d).HookUpCommand((ICommand)e.OldValue, (ICommand)e.NewValue); 
    } 

    private void RemoveCommand(ICommand command) 
    { 
     EventHandler handler = CanExecuteChanged; 
     command.CanExecuteChanged -= handler; 
    } 
} 
2

您可以将Button的IsDefault属性绑定到允许的TextBox的IsFocused属性,如下所示。

<TextBox x:Name="TB1" Grid.Row="0" Height="15" Width="300"> 

    </TextBox> 
    <TextBox x:Name="TB2" Grid.Row="1" Height="15" Width="300"> 

    </TextBox> 
    <Button Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center" Height="40" Width="200" Content="Button" 
      IsDefault="{Binding IsFocused, ElementName=TB2}" Click="Button_Click"> 
    </Button> 

我已经拥有它,所以IsEnabled属性被绑定,但它阻止了按钮点击的工作。然后我尝试基于TB2或按钮的重点进行多绑定,但如果TB1因为禁用的按钮无法接受点击以获得焦点,而仍然阻止点击。