【问题标题】:Form validation disable submit button until all fields are filled in WPF表单验证禁用提交按钮,直到所有字段都填写在 WPF 中
【发布时间】:2011-01-08 19:32:27
【问题描述】:

鉴于: 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 开始)。

【问题讨论】:

  • MVVM 不是一个框架,它是一个模式。模式应该用在代码更简洁的地方。那里有框架,但您只需要一个实现INotifyPropertyChanged 的类和一个实现ICommand 的命令。然而,框架只是让编写这些变得更容易,我怀疑这仍然比你可能遇到的另一个解决方案更容易

标签: c# wpf data-binding forms


【解决方案1】:

这可以使用 WPF 验证机制轻松完成。首先,由于您想遵循 WPF 架构,我建议您使用 WPF Command model

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

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

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

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

Validation in Windows Presentation Foundation

Using Custom Validation Rules in 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>

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

    }
}

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2020-03-14
    • 1970-01-01
    • 2020-11-12
    • 2018-01-22
    • 2011-08-02
    • 2014-07-25
    • 2015-06-10
    • 2013-05-21
    相关资源
    最近更新 更多