表单验证:在WPF中禁用提交按钮直到所有字段都填写完毕

6
给定: 基于WPF 4.0的桌面应用程序。有两个TextBox字段和提交按钮的基本输入表单。
XAML代码:
<Label Content="Username" />
<TextBox x:Name="Form_UserName" />

<Label Content="Password" />
<TextBox x:Name="Form_Password" />

<Button x:Name="Submit"
        Click="Form_Submit_Button_Click"
        Content="Submit" />

任务: 当且仅当两个TextBox字段填写时,启用提交按钮的逻辑。
传统解决此问题的方式是使用事件处理程序,例如onLostFocus(),在该事件处理程序中,我们可以控制每次用户从文本框切换焦点时这些字段的条件。
但由于我的项目是基于WPF的,我更喜欢使用原生表单处理机制-数据绑定机制。我阅读了一些关于表单验证的文章,包括来自该网站和MSDN的文章,但在几乎所有示例中,都建议使用MVVM框架,而我想不借助任何框架实现它。
另外,我试过使用IMultiValueConverter,但没有得到预期结果。
如何尽可能简单地通过数据绑定来解决这个问题(因为我只是刚开始学WPF)?

2
MVVM不是一个框架,而是一种模式。模式应该用于使代码更加清晰。虽然有许多框架可供选择,但你只需要一个实现了INotifyPropertyChanged接口的类和一个实现了ICommand接口的命令即可。然而,框架可以使编写这些内容变得更加容易,我相信这仍然比你可能遇到的其他解决方案更容易。 - aqwert
1个回答

8
这可以通过使用WPF验证机制轻松完成。首先,由于您想遵循WPF体系结构,建议您使用WPF命令模型
现在,要实现您的功能,可以将CommandBinding添加到Window / UserControl或Button本身中:
<Button Content="Save" Command="Save">

<Button.CommandBindings>
    <CommandBinding Command="Save" 
                    Executed="Save_Executed" CanExecute="Save_CanExecute" />
    </Button.CommandBindings>
</Button>

现在,您可以订阅CanExecute事件,根据您的验证逻辑启用或禁用按钮。在继续之前,我建议您阅读以下内容:Windows Presentation Foundation中的验证在WPF中使用自定义验证规则
实现您的要求最简单的方法如下: XAML
<Window x:Class="GridScroll.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:GridScroll"
    Title="Window1" Height="300" Width="300">

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="200"/>
    </Grid.ColumnDefinitions>

    <TextBlock Text="User Name" Grid.Column="0" Grid.Row="0"/>
    <TextBox Grid.Column="1" Grid.Row="0" Text="{Binding Path=UserName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
    <TextBlock Text="Password" Grid.Column="0" Grid.Row="1"/>
    <TextBox Grid.Column="1" Grid.Row="1" Text="{Binding Path=Password,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>

    <Button Content="Save" Grid.Row="2" Grid.ColumnSpan="2" Width="100" HorizontalAlignment="Right" Command="Save">
        <Button.CommandBindings>
            <CommandBinding Command="Save" 
                    Executed="Save_Executed" CanExecute="Save_CanExecute"/>
        </Button.CommandBindings>

    </Button>
</Grid>

代码后台

public partial class Window1 : Window,INotifyPropertyChanged
{
    public Window1()
    {
        InitializeComponent();
        DataContext = this;
    }

    private string userName;
    public string Username
    {
        get
        {
            return userName;
        }
        set
        {
            userName = value;
            OnPropertyChanged("UserName");
        }
    }

    private string password;
    public string Password
    {
        get
        {
            return password;
        }
        set
        {
            password = value;
            OnPropertyChanged("Password");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }

    private void Save_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        //Your code
    }

    private void Save_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = !(string.IsNullOrEmpty(Username) && string.IsNullOrEmpty(Password));

    }
}

希望这能帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接