【问题标题】:How to let View Model know about successfully validated form如何让 View Model 知道成功验证的表单
【发布时间】:2012-05-09 13:25:21
【问题描述】:

我有一个包含几个字段的注册表单。这是一个PRISM MVVM 应用程序。

其中一个字段的 XAML 如下所示(RegisterView.xaml):

<TextBlock>Surname</TextBlock>
<TextBox Validation.ErrorTemplate="{StaticResource validationTemplate}"      HorizontalAlignment="Left" Margin="0" Name="Surname" VerticalAlignment="Top" >
    <TextBox.Text>
        <Binding Path="Surname" UpdateSourceTrigger="LostFocus" >
            <Binding.ValidationRules>
                 <val:Required />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

从上面的代码可以看出,我使用类Required 来验证字段。类Required 的函数Validate() 然后返回ValidationResult 对象。我还为输入的样式定义了一些触发器,因此我能够在视图中向用户显示验证结果。

我不知道如何检测 ViewModel 中所有输入的验证状态。在 ViewModel 中,我有 SaveUserCanExecute 函数,它应该在所有输入的验证状态下启用/禁用注册表单提交按钮。

那么有没有什么简单的方法可以实现呢?

我可以为此做一些解决方法,但我认为这不是正确的方法。

现在我在提交按钮的 Click 事件触发的 View 代码中创建了一个 Submit_Click 函数。

在 RegisterView.xaml 中

<Button Content="Register" HorizontalAlignment="Left" Margin="0" Name="Submit" VerticalAlignment="Top" Command="{x:Static inf:Commands.SaveUser}" Click="Submit_Click" />

我还在后面的代码中创建了新的公共布尔变量“formIsValid”。当按下提交按钮时,我检查所有输入是否没有验证错误(使用Validation.GetHasError(InputName) 函数)。如果是,我将 formIsValid 变量设置为 true,否则,我将其设置为 false。

在 RegisterView.xaml.cs 中

private void Submit_Click(object sender, RoutedEventArgs e)
{
    if (Validation.GetHasError(Firstname) == false && Validation.GetHasError(Surname) == false)
    {
        registerFormValid = true;
    }
    else
    {
        registerFormValid = false;
    }
}

那么在 ViewModel 中SaveUserCanExecute 函数看起来是这样的:

private bool SaveUserCanExecute(string parameter)
{
    if (View.registerFormValid == true)
    {
        return true;
    }
    return false;
}

但正如我之前提到的,我认为这不是正确的方法,我正在寻找更清晰的方法。

【问题讨论】:

    标签: c# .net mvvm prism


    【解决方案1】:

    在您的 ViewModel 中实现 IDataErrorInfo,然后您就可以在 VM 中获得所需的所有信息。您的 XAML 只需要 ValidatesOnDataErrors=true

    <TextBlock>Surname</TextBlock>
    <TextBox Validation.ErrorTemplate="{StaticResource validationTemplate}"      HorizontalAlignment="Left" Margin="0" Name="Surname" VerticalAlignment="Top" >
            <TextBox.Text>
                <Binding Path="Surname" UpdateSourceTrigger="LostFocus" ValidatesOnDataErrors="True">
                </Binding>
            </TextBox.Text>
     </TextBox>
    

    编辑:检查 DelegeCommand 的使用,然后你的命令 CanExecute 可以简单地检查 string.IsNullOrEmpty(this.Error)。

    【讨论】:

    • 好的,听起来不错,但是如何正确实现 IDataErrorInfo 以返回验证结果?我检查了很多 IDataErrorInfo 示例,几乎所有这些示例都将一些验证函数放入 public string this[string propertyName] { validation functions here }。但我不希望这样,因为我已经使用 将验证函数绑定到 xaml 元素,并且我不想调用相同的函数两次。谢谢。
    • 如果我调用 MessageBox.Show(this.Error);在我的代码中,它什么都没有显示,甚至没有显示消息框。
    【解决方案2】:

    将命令 (ICommand) 绑定到您的提交按钮并在其 CanExecute 方法中实现此逻辑。这是一个经典的ICommand 实现。

    【讨论】:

    • 这是我做的有点不同的方式。我已将复合命令绑定到我的提交按钮(请参阅 Command="{x:Static inf:Commands.SaveUser}")。问题是,它的 CanExecute 函数在 ViewModel 中,所以这就是为什么我需要获取有关所有输入验证的信息。或者我没有得到你的答案。无论如何,谢谢。
    • 当你构造一个 ICommand 对象时,你同时改变了 Execute 和 CanExecute。这是在视图模型级别完成的,因此您可以传入现有方法。当任何输入元素焦点发生变化时,WPF 将自动调用 CanExecute。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 2020-05-14
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多