ValidationRule失败时属性绑定未更新

本文关键字:更新 绑定 属性 失败 ValidationRule | 更新日期: 2023-09-27 18:27:31

我的视图中有一些用于输入字段的TextBox和一个"保存"按钮。其中两个文本框是保存所需的字段,我在xaml中为一些视觉反馈(红色边框和工具提示)设置了一个自定义的ValidationRule,如下所示:

<TextBox ToolTip="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}">
    <TextBox.Text>
        <Binding Path="ScriptFileMap" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <v:MinimumStringLengthRule MinimumLength="1" ErrorMessage="Map is required for saving." />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

"保存"按钮链接到DelegateCommand,该命令调用SaveScript()函数。如果两个必填字段的属性为空,则该函数不允许用户保存:

public void SaveScript()
{
    if (this.ScriptFileName.Length > 0 && this.ScriptFileMap.Length > 0)
    {
        // save function logic
    }
}

但是,该函数仍然允许保存该文件。经过仔细检查,我发现当ValidationRule失败时,这两个字段(ScriptFileName和ScriptFileMap)的值没有更新,而是按最后一个已知值进行更新。

这是ValidationRule的预期行为吗?还是我遗漏了什么或出现了故障?如果是前者,有没有一种方法可以覆盖这种行为?如果从未将空字符串传递到绑定属性中,则无法阻止保存在ViewModel中。

ValidationRule失败时属性绑定未更新

是的,这是预期的行为。默认情况下,验证规则在原始建议值上运行,即转换并写回绑定源之前的值。

尝试将规则上的ValidationStep更改为UpdatedValue。这将强制规则在转换并写回新值之后运行。

您应该实现CanExecute方法和RaiseCanExecuteChanged事件,这将使您的按钮保持禁用状态,直到所有必需的属性都通过验证逻辑。

由于我从未使ValidationRule正常工作,我采取了不同的方法,只使用了一些绑定。这是我的文本框,带有文本、边框和工具提示的绑定:

<TextBox Text="{Binding Path=ScriptFileName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" BorderBrush="{Binding Path=ScriptFileNameBorder, UpdateSourceTrigger=PropertyChanged}" ToolTip="{Binding Path=ScriptFileNameToolTip, UpdateSourceTrigger=PropertyChanged}" />

这是我对文本字段的绑定,带有自己更新边框和工具提示的逻辑(无需验证):

public string ScriptFileName
        {
            get
            {
                return this.scriptFileName;
            }
            set
            {
                this.scriptFileName = value;
                RaisePropertyChanged(() => ScriptFileName);
                if (this.ScriptFileName.Length > 0)
                {
                    this.ScriptFileNameBorder = borderBrushNormal;
                    this.scriptFileNameToolTip.Content = "Enter the name of the file.";
                }
                else
                {
                    this.ScriptFileNameBorder = Brushes.Red;
                    this.scriptFileNameToolTip.Content = "File name is required for saving.";
                }
            }
        }

这样做可以让我在框为空时获得所需的用户反馈(红色边框和工具提示消息),并且仍然使用SaveScript函数中的代码来阻止"保存"按钮工作。

这有点像打字,因为我需要为我想成为必需的每个额外字段都有单独的属性,但我尝试的所有其他内容要么没有效果,要么破坏了程序中的其他内容(包括ValidationRules和DataTriggers)。