WPF 将命令附加到 NET 3.5 中 return 键上的文本框
WPF Attach a command to a textbox on return key in NET 3.5
我正在尝试将命令和命令参数附加到 return 键上的文本框,但没有成功。参数为同一文本框中的当前文本。
<TextBox x:Name="txtSearch">
<TextBox.InputBindings>
<KeyBinding Command="{Binding SearchCommand}"
CommandParameter="{Binding Path=Text, ElementName=txtSearch}" Key="Return" />
</TextBox.InputBindings>
</TextBox>
基本上我想在用户单击 return/enter 键时执行命令并将文本框中的当前文本作为参数传递。
我发现这个 link 据说在 .NET 3.5 中用于键绑定的命令参数不接受绑定。所以代码隐藏中的代码提出了一个解决方案,但是我如何从代码中将参数传递给命令?
首先,您需要将 KeyBinding 添加到您的 TextBox 并将其命令设置为代码隐藏。只需将其添加到视图的构造函数中:
public MainWindow()
{
InitializeComponent();
DataContext = new MyViewModel();
KeyBinding kb = new KeyBinding();
kb.Command = (DataContext as MyViewModel).SearchCommand;
kb.Key = Key.Enter;
txtSearch.InputBindings.Add(kb);
}
然后,您可以将名为 txtSearch
的文本框的 Text
属性 绑定到您的 ViewModel 的 属性。这样您就不需要传递参数,因为您可以在执行命令的代码中的 ViewModel 中使用 属性 的值。
您的 ViewModel 应如下所示:
public class MyViewModel : ObservableObject
{
private string _txtSearch;
public string TxtSearch
{
get { return _txtSearch; }
set
{
if (value != _txtSearch)
{
_txtSearch = value;
OnPropertyChanged("TxtSearch");
}
}
}
private ICommand _searchCommand;
public ICommand SearchCommand
{
get
{
if (_searchCommand == null)
{
_searchCommand = new RelayCommand(p => canSearch(), p => search());
}
return _searchCommand;
}
}
private bool canSearch()
{
//implement canExecute logic.
}
private void search()
{
string text = TxtSearch; //here you'll have the string that represents the text of the TextBox txtSearch
//DoSomething
}
}
如果您可以访问 C# 6(Visual Studio 2015 及更高版本),则可以将对 OnPropertyChanged 的调用更改为:OnPropertyChanged(nameof(TxtSearch));
。这样你就可以摆脱 "magic string" 并且最终重命名 属性 不会对你造成任何问题。
然后你的 XAML 应该看起来像这样:(注意你需要指定 te UpdateSourceTrigger 必须是 PropertyChanged,这样你的 ViewModel 的 TxtSearch
属性 保持不变到目前为止,当您点击文本框上的 Enter
键时。
<TextBox Text="{Binding TxtSearch, UpdateSourceTrigger=PropertyChanged}" x:Name="txtSearch"/>
您的 ViewModel 需要实施 INotifyPropertyChanged 并且您需要适当的 ICommand 实施。这里我将使用 RelayCommand。
这些实现如下所示。
由于您的框架是 .NET 3.5,因此实现它:
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
这是 RelayCommand 的实现:
public class RelayCommand : ICommand
{
private Predicate<object> _canExecute;
private Action<object> _execute;
public RelayCommand(Predicate<object> canExecute, Action<object> execute)
{
_canExecute = canExecute;
_execute = execute;
}
public bool CanExecute(object parameter)
{
return _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
我正在尝试将命令和命令参数附加到 return 键上的文本框,但没有成功。参数为同一文本框中的当前文本。
<TextBox x:Name="txtSearch">
<TextBox.InputBindings>
<KeyBinding Command="{Binding SearchCommand}"
CommandParameter="{Binding Path=Text, ElementName=txtSearch}" Key="Return" />
</TextBox.InputBindings>
</TextBox>
基本上我想在用户单击 return/enter 键时执行命令并将文本框中的当前文本作为参数传递。
我发现这个 link 据说在 .NET 3.5 中用于键绑定的命令参数不接受绑定。所以代码隐藏中的代码提出了一个解决方案,但是我如何从代码中将参数传递给命令?
首先,您需要将 KeyBinding 添加到您的 TextBox 并将其命令设置为代码隐藏。只需将其添加到视图的构造函数中:
public MainWindow()
{
InitializeComponent();
DataContext = new MyViewModel();
KeyBinding kb = new KeyBinding();
kb.Command = (DataContext as MyViewModel).SearchCommand;
kb.Key = Key.Enter;
txtSearch.InputBindings.Add(kb);
}
然后,您可以将名为 txtSearch
的文本框的 Text
属性 绑定到您的 ViewModel 的 属性。这样您就不需要传递参数,因为您可以在执行命令的代码中的 ViewModel 中使用 属性 的值。
您的 ViewModel 应如下所示:
public class MyViewModel : ObservableObject
{
private string _txtSearch;
public string TxtSearch
{
get { return _txtSearch; }
set
{
if (value != _txtSearch)
{
_txtSearch = value;
OnPropertyChanged("TxtSearch");
}
}
}
private ICommand _searchCommand;
public ICommand SearchCommand
{
get
{
if (_searchCommand == null)
{
_searchCommand = new RelayCommand(p => canSearch(), p => search());
}
return _searchCommand;
}
}
private bool canSearch()
{
//implement canExecute logic.
}
private void search()
{
string text = TxtSearch; //here you'll have the string that represents the text of the TextBox txtSearch
//DoSomething
}
}
如果您可以访问 C# 6(Visual Studio 2015 及更高版本),则可以将对 OnPropertyChanged 的调用更改为:OnPropertyChanged(nameof(TxtSearch));
。这样你就可以摆脱 "magic string" 并且最终重命名 属性 不会对你造成任何问题。
然后你的 XAML 应该看起来像这样:(注意你需要指定 te UpdateSourceTrigger 必须是 PropertyChanged,这样你的 ViewModel 的 TxtSearch
属性 保持不变到目前为止,当您点击文本框上的 Enter
键时。
<TextBox Text="{Binding TxtSearch, UpdateSourceTrigger=PropertyChanged}" x:Name="txtSearch"/>
您的 ViewModel 需要实施 INotifyPropertyChanged 并且您需要适当的 ICommand 实施。这里我将使用 RelayCommand。
这些实现如下所示。
由于您的框架是 .NET 3.5,因此实现它:
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
这是 RelayCommand 的实现:
public class RelayCommand : ICommand
{
private Predicate<object> _canExecute;
private Action<object> _execute;
public RelayCommand(Predicate<object> canExecute, Action<object> execute)
{
_canExecute = canExecute;
_execute = execute;
}
public bool CanExecute(object parameter)
{
return _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}