簡體   English   中英

防止按Enter鍵提交WPF表單

[英]Preventing WPF form submit on pressing Enter key

我有一個具有多個控件(文本框,組合框,按鈕等)的WPF XAML屏幕。 后面的代碼在C#中。 我為其中一個按鈕保留了IsDefault="True" 因此,如果用戶在任何文本框中按Enter鍵,則將提交表單。

我只需要為一個特定的文本框使用Enter鍵提交表單。 如果用戶在其他任何文本框中按Enter鍵,則我不希望提交表單。

我知道我可以使用后面的代碼(即*.xaml.cs )來實現此*.xaml.cs 但是,如何使用MVVM設計模式實現這一目標?

您可能不在乎用戶按下的是哪個文本框,而只是希望填寫完整的表格。 在這種情況下,請執行驗證並使用綁定禁用按鈕。

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.
}

您可以將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或Button的焦點對其進行多重綁定,但是如果TB1處於焦點狀態,那仍然會阻止單擊,因為禁用的按鈕無法接受單擊來獲得焦點。

只需在要處理的文本框上設置AcceptsReturn="True"即可自行輸入,而不是路由到表單。

您可以從按鈕中刪除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;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM