我有一个WPF XAML屏幕有多个控件(文本框,组合框,按钮等)。后面的代码是用C#编写的。我为其中一个按钮保留了IsDefault="True"
。因此,如果用户在任何文本框中按输入键,表单将被提交。防止WPF窗体按Enter键提交
我需要提交表格使用输入键只为一个特定的文本框。如果用户按下在任何其他文本框中输入键,我不希望表单被提交。
我知道我可以用后面的代码来实现这个(即*.xaml.cs
)。但是,如何使用MVVM设计模式来实现这一点?
我有一个WPF XAML屏幕有多个控件(文本框,组合框,按钮等)。后面的代码是用C#编写的。我为其中一个按钮保留了IsDefault="True"
。因此,如果用户在任何文本框中按输入键,表单将被提交。防止WPF窗体按Enter键提交
我需要提交表格使用输入键只为一个特定的文本框。如果用户按下在任何其他文本框中输入键,我不希望表单被提交。
我知道我可以用后面的代码来实现这个(即*.xaml.cs
)。但是,如何使用MVVM设计模式来实现这一点?
只需在要处理的文本框上设置AcceptsReturn="True"
即可自行输入,而不是路由到表单。
这可行,但将文本框变成多行文本框。有什么办法可以防止这种情况发生? – Zack
不像我在Windows 8/10上看到MaxLines属性无法正常工作那么远。我认为你可能不得不通过一个键盘事件处理程序来获取派生的控件,从而吞下按键。 –
你可能不在乎用户按下哪个文本框输入,你只是想要完成整个表单。如果是这种情况,请执行验证并使用绑定禁用按钮。
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.
}
感谢FrumRoll的评论。但正如我所提到的,我只需要在用户按下一个特定的文本框中输入时提交表单(可以说txtboxProductKey)。不管用户是否输入了任何其他文本框,都不会触发表单提交txtboxProductKey中的值。 –
@Vineetv你当然可以验证所有的绑定值,而不仅仅是ProductKey。但是,如果您只想使用单个文本框来触发该命令,则会从按钮中删除IsDefault =“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;
}
}
您可以将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因为禁用的按钮无法接受点击以获得焦点,而仍然阻止点击。
创建附加的行为,将连接相应的键事件来处理输入密钥。 –
嗯,这是代码隐藏的工作,因为这是视图逻辑。 – Dennis