表单验证禁用提交按钮,直到WPF中填写所有字段

时间:2022-11-24 11:00:24

Given: WPF 4.0 desktop-based application. Basic input form with two TextBox fields and submit button.

鉴于:WPF 4.0基于桌面的应用程序。带有两个TextBox字段和提交按钮的基本输入表单。

XAML-code:

<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" />

Task: Implement logic where submit button is enabled if and only if two TextBox fields are filled.

任务:当且仅当填充了两个TextBox字段时,实现启用提交按钮的逻辑。

The classical way to solve this issue is a use of event handlers such as onLostFocus() or something like that, where we can control condition of this fields every time when user switch focus from the field.

解决此问题的经典方法是使用事件处理程序,如onLostFocus()或类似的东西,我们可以在每次用户从字段切换焦点时控制此字段的条件。

But since my project is WPF-based, I prefer to use a native way to work with forms — DataBinding mechanism. I read some articles from this site and MSDN too about form validation, but in almost all examples is proposed to use MVVM framework and I would like to implement it without any framework.

但由于我的项目是基于WPF的,我更喜欢使用本机方式来处理表单--DataBinding机制。我从这个站点和MSDN上读了一些关于表单验证的文章,但几乎所有的例子都提出使用MVVM框架,我想在没有任何框架的情况下实现它。

Also, I tried to play with IMultiValueConverter but no worked result is received.

此外,我尝试使用IMultiValueConverter,但没有收到任何工作结果。

Please, point me to (code) suggestion how to solve this problem with Databinding as simple as possible (I'm only starting with WPF).

请指点(代码)建议如何使用Databinding尽可能简单地解决这个问题(我只是从WPF开始)。

1 个解决方案

#1


8  

This can be easily done using the WPF validation mechanisms. First since you want to follow the WPF architecture I would reccomend you to use the WPF Command model.

使用WPF验证机制可以轻松完成此操作。首先,因为您想要遵循WPF架构,我建议您使用WPF Command模型。

Now to implement your functionality, you can add a CommandBinding to the Window/UserControl or to the Button itself:

现在要实现您的功能,您可以将CommandBinding添加到Window / UserControl或Button本身:

<Button Content="Save" Command="Save">

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

Now you can subscribe to the CanExecute event to enable or disable your button based on your validation logic. I recommend these reads before you continue:

现在,您可以订阅CanExecute事件,以根据验证逻辑启用或禁用您的按钮。在继续之前我建议您阅读这些内容:

Validation in Windows Presentation Foundation

Windows Presentation Foundation中的验证

Using Custom Validation Rules in WPF

在WPF中使用自定义验证规则

The simplest way to do your requirement is as given below:

满足您要求的最简单方法如下:

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>

Code behind

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));

    }
}

Hope this helps.

希望这可以帮助。

#1


8  

This can be easily done using the WPF validation mechanisms. First since you want to follow the WPF architecture I would reccomend you to use the WPF Command model.

使用WPF验证机制可以轻松完成此操作。首先,因为您想要遵循WPF架构,我建议您使用WPF Command模型。

Now to implement your functionality, you can add a CommandBinding to the Window/UserControl or to the Button itself:

现在要实现您的功能,您可以将CommandBinding添加到Window / UserControl或Button本身:

<Button Content="Save" Command="Save">

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

Now you can subscribe to the CanExecute event to enable or disable your button based on your validation logic. I recommend these reads before you continue:

现在,您可以订阅CanExecute事件,以根据验证逻辑启用或禁用您的按钮。在继续之前我建议您阅读这些内容:

Validation in Windows Presentation Foundation

Windows Presentation Foundation中的验证

Using Custom Validation Rules in WPF

在WPF中使用自定义验证规则

The simplest way to do your requirement is as given below:

满足您要求的最简单方法如下:

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>

Code behind

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));

    }
}

Hope this helps.

希望这可以帮助。