2016-11-18 19 views
0

複数のコントロール(テキストボックス、コンボボックス、ボタンなど)を持つWPF XAML画面があります。コードの背後にはC#があります。私はIsDefault="True"をボタンの1つにしておきました。このため、ユーザーがを押すと、いずれかのテキストボックスにキーを入力すると、フォームが送信されます。Enterキーを押したときのWPFフォーム送信の防止

フォームを提出する必要がありますのキーを特定のテキストボックスにのみ入力してください。ユーザーがを押した場合他のテキストボックスにキーを入力しても、フォームを送信しないようにします。

私はこれを達成するために、コードの背後にあるコード(例:*.xaml.cs)を使用しています。しかし、MVVMデザインパターンを使用してこれをどのように達成できますか?

+0

Enterキーを処理するために、適切なキーイベントを接続する動作を作成します。 –

+1

これはビューロジックなので、コードビハインドの作業です。 – Dennis

答えて

1

フォームにルーティングするのではなく、処理するテキストボックスにAcceptsReturn="True"を入力するだけで、自分で入力してください。

+0

これは動作しますが、テキストボックスは複数行のテキストボックスになります。それを防ぐ方法はありますか? – Zack

+0

MaxLinesプロパティが正常に動作しないWindows 8/10で私が見る限りではありません。私はあなたがkeypressを飲み込むキーボードイベントハンドラを持つ派生したコントロールに頼らなければならないかもしれないと思います。 –

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ありがとうございます。しかし、私が言及したように、ユーザーが特定のテキストボックス(Enter 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がフォーカスされていればクリックができなくなりました。

関連する問題