Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在文本框中捕获Enter键不会';行不通_C#_Wpf_Xaml_Mvvm_Mvvm Light - Fatal编程技术网

C# 在文本框中捕获Enter键不会';行不通

C# 在文本框中捕获Enter键不会';行不通,c#,wpf,xaml,mvvm,mvvm-light,C#,Wpf,Xaml,Mvvm,Mvvm Light,在我看来,我试图通过以下XAML将事件绑定到Enter键: <TextBox x:Name="txtFields" Text="{Binding FieldsTextProperty, UpdateSourceTrigger=PropertyChanged}" Height="23" TextWrapping="NoWrap" Background="#FFCBEECD" AcceptsReturn="False" > <TextBox.InputBinding

在我看来,我试图通过以下XAML将事件绑定到Enter键:

<TextBox x:Name="txtFields" Text="{Binding FieldsTextProperty, UpdateSourceTrigger=PropertyChanged}" Height="23" TextWrapping="NoWrap" Background="#FFCBEECD" AcceptsReturn="False" >
        <TextBox.InputBindings>
            <KeyBinding Key="Enter" Command="{Binding AddFieldCommand}"></KeyBinding>
        </TextBox.InputBindings>
</TextBox>
在ViewModel构造函数中,存在以下
RelayCommand

AddFieldCommand = new RelayCommand(AddField);
RelayCommand
调用方法
AddField

public void AddField()
{
   Console.WriteLine("AddField Method")
}

这不起作用-从未调用AddField方法。有人能帮忙吗?

我想知道.InputBindings在这种情况下是否不起作用。键盘输入处理可能被文本框劫持

假设您希望坚持MVVM模式并避免代码背后的事件处理代码,我可能会选择创建TextBox的自定义实现—称之为“SubmitTextBox”

自定义SubmitTextBox可以自动连接到PreviewKeyDown事件,并监视Enter键

您可以通过添加ICommand DP来处理“提交”事件,从而进一步遵守MVVM

像这样的

public class SubmitTextBox : TextBox
{
    public SubmitTextBox()
        : base()
    {
        PreviewKeyDown += SubmitTextBox_PreviewKeyDown;
    }

    private void SubmitTextBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        if (e.Key == System.Windows.Input.Key.Enter)
        {
            if (this.SubmitCommand != null && this.SubmitCommand.CanExecute(this.Text))
            {
                // Note this executes the command, and returns
                // the current value of the textbox.
                this.SubmitCommand.Execute(this.Text);
            }
        }
    }

    /// <summary>
    /// The command to execute when the text is submitted (Enter is pressed).
    /// </summary>
    public ICommand SubmitCommand
    {
        get { return (ICommand)GetValue(SubmitCommandProperty); }
        set { SetValue(SubmitCommandProperty, value); }
    }

    // Using a DependencyProperty as the backing store for SubmitCommand.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SubmitCommandProperty =
        DependencyProperty.Register("SubmitCommand", typeof(ICommand), typeof(SubmitTextBox), new PropertyMetadata(null));
}
公共类SubmitTextBox:TextBox
{
公开提交文本框()
:base()
{
PreviewKeyDown+=SubmitTextBox\u PreviewKeyDown;
}
私有void SubmitTextBox_PreviewKeyDown(对象发送方,System.Windows.Input.KeyEventArgs e)
{
if(e.Key==System.Windows.Input.Key.Enter)
{
if(this.SubmitCommand!=null&&this.SubmitCommand.CanExecute(this.Text))
{
//注意,这将执行命令,并返回
//文本框的当前值。
this.SubmitCommand.Execute(this.Text);
}
}
}
/// 
///提交文本时要执行的命令(按Enter键)。
/// 
公共ICommand提交命令
{
获取{return(ICommand)GetValue(SubmitCommandProperty);}
set{SetValue(SubmitCommandProperty,value);}
}
//使用DependencyProperty作为SubmitCommand的备份存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性SubmitCommandProperty=
DependencyProperty.Register(“SubmitCommand”、typeof(ICommand)、typeof(SubmitTextBox)、newpropertyMetadata(null));
}
您的XAML最终会变成这样:

<custom:SubmitTextBox 
  x:Name="txtFields"
  Text="{Binding FieldsTextProperty}"
  SubmitCommand="{Binding AddFieldCommand}" 
  Height="23" 
  TextWrapping="NoWrap"
  Background="#FFCBEECD" />

希望有帮助:)

更新:为了澄清,我创建的SubmitCommand返回文本框中的当前文本作为参数。为了在MVVM Light toolkit中使用它,您需要创建一个可以接受“string”类型的RelayCommand

public RelayCommand<string> AddFieldCommand { get; private set; }

public ViewModelConstructor()
{
   AddFieldCommand = new RelayCommand<string>(AddField);
}

private void AddField(string text)
{
   // Do something
}
public RelayCommand AddFieldCommand{get;private set;}
公共ViewModelConstructor()
{
AddFieldCommand=新的RelayCommand(AddField);
}
私有void AddField(字符串文本)
{
//做点什么
}

我希望这能澄清一点:)

这不是由
AcceptsReturn=“false”
引起的吗?@KingKing不,
AcceptsReturn=“false”
防止断线。您是否尝试过在方法
AddField
中设置断点?不要期望控制台出现并打印一些消息供您查看。@KingKing是的,我在方法中尝试了断点-断点从未激活。谢谢!你能解释一下我是如何在我的ViewModel中使用SubmitTextBox类的吗?我也有同样的问题。没有必要在你的ViewModel中使用SubmitTextBox。新文本框的实例是在XAML中创建的。。。你所需要做的就是坚持下去。在ViewModel上,创建一个ICommand(如果使用的是MVVMLight,则为RelayCommand),用于在提交文本时执行所需的操作。然后将该命令绑定到SubmitTextBox上的“SubmitCommand”。希望这是有意义的:)那么这在ViewModel中应该足够了<代码>添加字段命令=新的中继命令(SubmitCommand)是的,我正在使用MVVMLight:)查看您的原始代码,我希望它的内容是:AddFieldCommand=newrelaycommand(AddField)。。。但是,这是最基本的想法。然后确保在XAML中的SubmitTextBox上有SubmitCommand=“{Binding AddFieldCommand}”命令绑定。我收到一些绑定错误:“在对象”“类数据”“上找不到FieldsTextProperty”属性。BindingExpression:Path=FieldsTextProperty;DataItem='ClassData';目标元素是“SubmitTextBox”(Name='txtFields');在“对象”“类数据”上找不到目标属性为“文本”(类型为“字符串”)“AddFieldCommand”属性。BindingExpression:Path=AddFieldCommand;DataItem='ClassData';目标元素是“SubmitTextBox”(Name='txtFields');目标属性为“SubmitCommand”(类型为“ICommand”)
public RelayCommand<string> AddFieldCommand { get; private set; }

public ViewModelConstructor()
{
   AddFieldCommand = new RelayCommand<string>(AddField);
}

private void AddField(string text)
{
   // Do something
}