提问人:Pomodoro 提问时间:4/4/2023 更新时间:4/5/2023 访问量:34
在文本框中插入相同的值 2 次,并检查这些值是否相同 WPF
Insert same value in textbox 2 times and checking the values are the same WPF
问:
我正在尝试在 WPF 中实现文本框的功能,以便需要插入一个值 2 次才能被接受为值,否则我需要显示一个错误,例如验证错误等。 我需要在文本框中插入一个值(es:'asd'),然后按 Tab 键文本消失,焦点保留在 texbox 中,然后我需要再次输入相同的文本才能被接受。
现在,我正在尝试通过处理文本框的 PreviewKeyInput 中代码隐藏中的值来做到这一点,但我正试图找到一个更优雅的解决方案。
答:
0赞
Frenchy
4/5/2023
#1
你可以研究这个样本来帮助你。我正在使用 Caliburn.Micro 来实现 MVVM
如果您对 caliburn 不满意,我解释一下:
创建一个名为 Test 的 wpf .Net 项目,禁止显示创建的文件。
MainWindow
创建一个名为 和 视图模型(类)的窗口(它存在于 Caliburn 中具有名称的逻辑)
MainView
MainViewModel
添加一个名为
Bootstrapper.cs
将 App.xaml 替换为:
<Application x:Class="Test.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Test">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<local:Bootstrapper x:Key="Bootstrapper" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
修改文件 Bootstrapper.cs:
using Caliburn.Micro;
using System.Windows;
namespace Test
{
public class Bootstrapper : BootstrapperBase
{
public Bootstrapper()
{
Initialize();
}
protected override async void OnStartup(object sender, StartupEventArgs e)
{
await DisplayRootViewForAsync<MainViewModel>();
}
}
}
修改 MainView.xaml:
<Window x:Class="Test.MainView"
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:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
Title="MainView" Height="450" Width="800">
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBox x:Name="Login" Width="200" Height="60" Margin="10,10,30,10" Background="AliceBlue" Focusable="True"
cal:Message.Attach="[Event LostFocus] = [Action Login_LostFocus($source, $eventargs)];
[Event GotFocus] = [Action Login_GotFocus($source, $eventargs)]"
FontSize="12" VerticalContentAlignment="Center" FontWeight="Medium"/>
<Label Name="Validation" Height="60" Width="400" VerticalContentAlignment="Center"/>
<Button x:Name="Quit" Content="Quit" Height="60" Width="70" Focusable="True"/>
</StackPanel>
</Grid>
</Window>
修改 MainViewModel:
using Caliburn.Micro;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Test
{
public class MainViewModel : Screen
{
public string FirstLogin { get; set; }
private string login;
public string Login
{
get { return login; }
set
{
if (login != value)
{
login = value;
NotifyOfPropertyChange(() => Login);
}
}
}
private string message;
public string Message
{
get { return message; }
set
{
if (message != value)
{
message = value;
NotifyOfPropertyChange(() => Message);
}
}
}
private string validation;
public string Validation
{
get { return validation; }
set
{
if (validation != value)
{
validation = value;
NotifyOfPropertyChange(() => Validation);
}
}
}
public async void Login_LostFocus(TextBox sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(FirstLogin))
{
FirstLogin = Login;
Login = "";
//needed before to set focus on TextBox again
await Task.Delay(100);
sender.Focus();
}
else
{
if (FirstLogin.Equals(Login))
Validation = "Its Ok!!";
else
Validation = "Its not Ok!!";
}
}
public void Login_GotFocus(TextBox sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(FirstLogin) && !string.IsNullOrEmpty(Login))
{
FirstLogin = "";
Login = "";
}
if (string.IsNullOrEmpty(FirstLogin))
Validation = "First Try";
else
Validation = "Second Try";
}
public MainViewModel()
{
FirstLogin = "";
Login = "";
Validation = "";
}
}
}
我没有设置按钮退出的操作,它的存在只是为了在TextBox上按Tab键时获得焦点
仅供参考,Caliburn 使用视图文件中的 Control 名称来链接 viewModel 中具有相同名称的属性。
评论
0赞
Pomodoro
4/6/2023
Thansk,我现在没有使用 Caliburn.Micro,但我设法找到了一个像您的解决方案一样,通过在 keydown 事件中处理视图代码隐藏中文本框的值(不是真正符合 mvvm 但是......由于 Textbox.Text 绑定到自定义类属性 (es MyClass.Text),我在类中添加了第二个属性 (TextCheck),首先在键中我检查 TextCheck 是否为空,如果是这样,我分配 TextCheck = Textbox.Text,然后像您一样恢复文本框中的焦点。谢谢。
0赞
Frenchy
4/6/2023
很乐意为您提供帮助,不要忘记验证/点赞答案以结束问题
评论