[英]Why does a command bound to a textbox not fire in wpf?
I've bound the textbox to a command using the trigger but nothing appears to happen when the user hits enter on the keyboard. 我已经使用触发器将文本框绑定到命令,但是当用户在键盘上按下Enter键时似乎什么也没有发生。 Why would that be? 为什么会这样呢? What I want to happen is when the user hits enter it appends the name to the list and clears the input field. 我想发生的是,当用户点击Enter时,它将名称添加到列表中并清除了输入字段。
The main areas of focus are here: xaml snippet 这里关注的主要领域是:xaml片段
<TextBox Grid.Row="0" Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged}">
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding Path=CmdSomething, UpdateSourceTrigger=PropertyChanged}"/>
</TextBox.InputBindings>
</TextBox>
and its calling this command in the main view model: 并在主视图模型中调用此命令:
public void CmdSomething()
{
Console.WriteLine(InputText);
}
Below is the code for the entire project just in case someone needs it to test. 下面是整个项目的代码,以防万一有人需要对其进行测试。
PROJECT CODE 项目代码
VNodes.cs VNodes.cs
namespace WpfApplication1
{
public class VNode
{
public string Name { get; set; }
}
}
MainWindow.xaml MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:local="clr-namespace:WpfApplication1">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged}">
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding Path=CmdSomething, UpdateSourceTrigger=PropertyChanged}"/>
</TextBox.InputBindings>
</TextBox>
<ListBox Grid.Row="1" Background="LightBlue" ItemsSource="{Binding VNodes}">
<ListBox.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
</WrapPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
MainViewModel MainViewModel
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using System.Collections.ObjectModel;
namespace WpfApplication1
{
public class MainViewModel : ObservableObject
{
private ObservableCollection<VNode> _vnodes;
public ObservableCollection<VNode> VNodes
{
get { return _vnodes; }
set
{
_vnodes = value;
NotifyPropertyChanged("VNodes");
}
}
private string _inputText = "";
public string InputText
{
get { return _inputText; }
set
{
if (value != _inputText)
{
_inputText = value;
}
}
}
public void CmdSomething()
{
Console.WriteLine(InputText);
}
public MainViewModel()
{
//hard coded data for testing
VNodes = new ObservableCollection<VNode>();
List<string> names = new List<string>() { "Tammy", "Doug", "Mike", "Joey", "Leslie", "Emily", "Tom" };
foreach(string name in names)
{
VNode item = new VNode();
item.Name = name;
VNodes.Add(item);
}
}
}
}
ObservableObjects.cs ObservableObjects.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace WpfApplication1
{
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
CmdSomething in your code is not a ICommand but instead just a function. 代码中的CmdSomething不是ICommand,而是函数。
Now there are two ways to make it work in your case. 现在,有两种方法可以使其适合您的情况。
Create an ICommand. 创建一个ICommand。 Wonderful tutorial . 精彩的教程 。
If MyCommand is a property of type ICommand in your ViewModel, then to bind your Custom Command : 如果MyCommand是ViewModel中ICommand类型的属性,则绑定您的Custom Command:
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding MyCommand, Mode=OneWay}" />
</TextBox.InputBindings>
And if you want to call your function, then you can use CallMethodAction behavior. 并且,如果要调用函数,则可以使用CallMethodAction行为。 Discussion . 讨论 。 You can search google for more tutorials. 您可以在Google中搜索更多教程。
For your current issue, this works without any issues whatsoever : 对于您当前的问题,此方法没有任何问题:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" xmlns:i =“ http://schemas.microsoft.com/expression/2010/interactivity” xmlns:ei =“ http://schemas.microsoft.com/expression/2010/interactions”
<TextBox x:Name="textBox" Margin="144,80,288,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Height="32">
<i:Interaction.Triggers>
<ei:KeyTrigger Key="Return"> <!-- Note Blend Behaviors don't use Enter, instead use Return value -->
<ei:CallMethodAction TargetObject="{Binding DataContext, RelativeSource={RelativeSource AncestorType={x:Type Window}, Mode=FindAncestor}}" MethodName="CmdSomething"/>
</ei:KeyTrigger>
</i:Interaction.Triggers>
</TextBox>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.