就是一个简单的回车触发事件的例子。在该例子中按下回车消息框会返回文本框输入的内容
C#代码:
using System.Printing;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace practice
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void TextBox_TextChanged(object sender, KeyEventArgs e)
{
if(e.Key == Key.Enter)
{
MessageBox.Show($"{textbox.Text}");
}
}
//Key Event Arguments键盘事件参数
}
}
Extensible Application Markup Langguage:
<Window x:Class="practice.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:practice"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid Margin="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox x:Name="textbox" KeyDown="TextBox_TextChanged" FontSize="87"/>
</Grid>
</Window>
如果想在MVVM中也使用Enter下发,会有亿点点复杂。
在MVVM架构中,为TextBox实现回车下发机制(即在用户按下回车键时执行某些操作)确实需要一些额外的考虑,因为MVVM强调视图(View)和视图模型(ViewModel)之间的分离。不过,这并不意味着必须采用非常复杂的方法,如事件聚合器,或者接受潜在的风险来使用控件自带的事件。
以下是在MVVM架构中实现TextBox回车下发机制的方法,同时保持视图和视图模型之间的分离:
使用附加行为(Attached Behavior):
附加行为是一种将特定功能附加到WPF控件上的技术,而不需要修改控件本身的代码。您可以创建一个附加行为来处理TextBox的KeyDown事件,并在其中检查是否按下了回车键。如果是,则调用视图模型上的某个方法。这样,您可以将事件处理逻辑与视图模型分离,同时仍然能够在XAML中声明性地应用它。
<TextBox Grid.Row="1" Grid.Column="2" Height="50" Width="200" Text="{Binding TextBoxText3, UpdateSourceTrigger=Explicit}"
local:TextBoxEnterBehavior.EnterCommand="{Binding UpdateTextCommand}" />
前台的TextBox绑定一个附加行为,目标是实现enter下发。这里的数据绑定更新触发方式为Explicit,就是只有通过显式赋值才可以触发。不会像前两个框图里的实时改变,失焦改变。
后台一个是要定义附加行为相关代码。一个是要定义事件。一个还要绑定属性。
代码:
XAML:
<Window x:Class="回车下发.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:回车下发"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Margin="30">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Height="50" Width="200" Background="#FFEEEEEE" Text="{Binding TextBoxText1}"/>
<TextBlock Grid.Row="0" Grid.Column="1" Height="50" Width="200" Background="#FFEEEEEE" Text="{Binding TextBoxText2}"/>
<TextBlock Grid.Row="0" Grid.Column="2" Height="50" Width="200" Background="#FFEEEEEE" Text="{Binding TextBoxText3}"/>
<TextBox Grid.Row="1" Grid.Column="0" Height="50" Width="200" Text="{Binding TextBoxText1,UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Grid.Row="1" Grid.Column="1" Height="50" Width="200" Text="{Binding TextBoxText2,UpdateSourceTrigger=Default}"/>
<TextBox Grid.Row="1" Grid.Column="2" Height="50" Width="200" Text="{Binding TextBoxText3, UpdateSourceTrigger=Explicit}"
local:TextBoxEnterBehavior.EnterCommand="{Binding UpdateTextCommand}"/>
</Grid>
</Window>
后台:
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace 回车下发
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext=new ViewModel();
}
}
}
文件一:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows;
namespace 回车下发
{
// AttachedBehavior.cs
public static class TextBoxEnterBehavior
{
// 定义一个依赖属性来存储要执行的命令
public static readonly DependencyProperty EnterCommandProperty =
DependencyProperty.RegisterAttached(
"EnterCommand",
typeof(ICommand),
typeof(TextBoxEnterBehavior),
new PropertyMetadata(null, OnEnterCommandChanged));
// 获取依赖属性的值
public static ICommand GetEnterCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(EnterCommandProperty);
}
// 设置依赖属性的值
public static void SetEnterCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(EnterCommandProperty, value);
}
// 当EnterCommand属性改变时的回调
private static void OnEnterCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TextBox textBox = d as TextBox;
if (textBox != null)
{
textBox.KeyDown -= TextBox_KeyDown;
ICommand command = (ICommand)e.NewValue;
if (command != null)
{
textBox.KeyDown += TextBox_KeyDown;
}
}
}
// 处理TextBox的KeyDown事件
private static void TextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
TextBox textBox = sender as TextBox;
if (textBox != null)
{
ICommand command = GetEnterCommand(textBox);
if (command != null && command.CanExecute(textBox.Text))
{
command.Execute(textBox.Text);
}
}
}
}
}
}
ViewModel:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace 回车下发
{
class ViewModel:BindableBase
{
private string _textBoxText1="实时改变";
public string TextBoxText1
{
get { return _textBoxText1; }
set
{
SetProperty(ref _textBoxText1, value);
}
}
private string _textBoxText2 = "失焦改变";
public string TextBoxText2
{
get { return _textBoxText2; }
set
{
SetProperty(ref _textBoxText2, value);
}
}
private string _textBoxText3 = "enter改变";
public string TextBoxText3
{
get { return _textBoxText3; }
set
{
SetProperty(ref _textBoxText3, value);
}
}
//定义命令,绑定命令,被执行的命令
public ICommand UpdateTextCommand { get; private set; }
public ViewModel()
{
UpdateTextCommand = new DelegateCommand<string>(param => UpdateText(param));
}
//命令执行内容
private void UpdateText(string text)
{
//就是在这里更新属性的
TextBoxText3=text;
System.Diagnostics.Debug.WriteLine("Text updated: " + text);
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}