WPF:Validation.ErrorTemplate未显示

5

我有一个模板,用于在控件周围显示红色边框和错误消息。它可以在TextBox和ComboBox上正常工作,但在两个特定的ComboBox上却不行。
那么让我们看看VM中有什么不同:

  • 由于我在基类中具有通用验证实现,因此没有变化
  • 显示相同类型的异步加载数据,仅使用一个面板的验证正常工作

所以简而言之,VM中没有任何区别。
视图完全相同,应用了相同的样式,因此简而言之,在这方面没有任何区别

所以我添加了NotifyOnValidationError=True到已经存在的ValidatesOnDataErrors=True,并订阅了Validation.Error...... 然后它被触发了!但是模板仍然没有显示出来。 我没有主意了,请建议我要检查的事情!

编辑:进一步研究:

我反编译了DataErrorValidationRule,并重新编译为MyDataErrorValidationRule,尽可能接近原始版本。我删除了ValidatesOnDataErrors=True,并添加了我的ValidationRule进行调试。它返回带有正确错误消息的str两次的new ValidationResult(false, (object)str); - 一次是将属性设置为null,另一次是强制验证整个对象。 模板仍然没有显示。

我还检查了控件上的Validation.GetErrorTemplate(在第一次触发Validation.Error时),它不是NULL,因此也不是DynamicResource出错了。

编辑:工作示例:

<ItemsControl ItemsSource="{Binding QuestionAnswers}">
                <ItemsControl.Resources>
                    <!-- ... -->
                    <DataTemplate DataType="{x:Type Model:QuestionAnswerModel}">
                        <StackPanel>
                                <!-- here is the combo box -->
                                <ComboBox Margin="8,4" Padding="8" MinWidth="120" HorizontalAlignment="Left" 
                                          Validation.ErrorTemplate="{DynamicResource DefaultValidationErrorTemplate}" 
                                          ItemsSource="{Binding Options.Source}"
                                          DisplayMemberPath="ItemName" SelectedValuePath="ItemID"
                                          SelectedValue="{Binding Options.SelectedID, ValidatesOnDataErrors=true}" />

                            </StackPanel>
                    </DataTemplate>
                </ItemsControl.Resources>
            </ItemsControl>

错误示例:

<ComboBox Margin="8,4" Padding="8" MinWidth="120" HorizontalAlignment="Left"
                          Validation.ErrorTemplate="{DynamicResource DefaultValidationErrorTemplate}"
                          SelectedItem="{Binding Type.SelectedItem, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" Validation.Error="ComboBox_Error"
                          ItemsSource="{Binding Type.Source}"
                          DisplayMemberPath="Localized"
                          >

它们来自于同一个XAML文件,包含工作ComboBox的ItemsControl与不工作的ComboBox在同一个Grid中。

唯一的区别是绑定的是SelectedItem还是SelectedValue,但这不应该对验证造成任何影响...


1
你能上传一个可工作的示例来说明你的问题吗? - blindmeis
你能否在运行时使用 Snoop 检查你的设置?在你的情况下,Validation.ErrorTemplate 的 ValueSource 应该是 Style。我无法使你的代码工作,因为我缺少验证等内容。 - blindmeis
2个回答

1

我曾经遇到过这个问题,即使事件已经触发,错误模板仍然没有显示,而且我永远无法弄清楚为什么它只会发生在某些控件上而不是其他控件。

最终我找到的解决方法是,在绑定的ValidationRule上将ValidationStep设置为ConvertedProposedValue

<TextBox>
  <TextBox.Text>
    <Binding Path="MyField">
      <Binding.ValidationRules>
        <Validation:MyValidationRule ValidationStep="ConvertedProposedValue" Message="Please enter a value." />
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>

对我来说,那似乎解决了问题!

编辑:如果您正在使用IDataErrorInfo,您可以尝试(尽管我个人没有测试过):

<Binding Path="MyField" ValidatesOnExceptions="True">
  <Binding.ValidationRules>
    <DataErrorValidationRule ValidationStep="ConvertedProposedValue" />
  </Binding.ValidationRules>
</Binding>

请删除 ValidatesOnDataErrors=True,这只是包含单个 <DataErrorValidationRule /> 的快捷方式。

你能给我提供一些链接,让我了解你是如何想到这个的吗?我以前从未使用过手动ValidationRules!!! - TDaver
同时,消息应该从数据(属性...)中获取,那么我该如何填充它? - TDaver
我正在通过我的自定义类对System.Windows.Controls.ValidationRule进行子类化以满足自己的需求。如果您正在使用IDataErrorInfo,您可以尝试相同的方法(请参见编辑后的帖子)。 - Ross
键入:<ComboBox.SelectedItem><Binding Path="Type.SelectedItem" NotifyOnValidationError="True" ><Binding.ValidationRules><DataErrorValidationRule ValidationStep="ConvertedProposedValue" /> </Binding.ValidationRules> </Binding> </ComboBox.SelectedItem>,我收到的异常信息是:验证规则 'System.Windows.Controls.DataErrorValidationRule' 收到了意外的值 ''。(这可能是由于将错误的 ValidationStep 分配给规则造成的。) - TDaver
TDaver: 我在SelectedValue上进行了绑定,而不是SelectedItem,效果很好。虽然我已经有一段时间没用SelectedItem了,但我认为这种方式不能与SelectedItem一起使用(免责声明:我可能在想其他事情 - 正如我所说的,这是很久以前的事情)。像这样:<ComboBox.SelectedValue> <Binding Path="StatusId" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <DataErrorValidationRule /> </Binding.ValidationRules> </Binding> </ComboBox.SelectedValue> - MetalMikester
@MetalMikester:我已经更改了绑定,使用SelectedValue而不是SelectedItem(在非操作性的绑定上),但仍然没有成功... - TDaver

0
我会检查以下内容:
  • 检查您的ComboBox的datacontext和binding是否正常工作,并且是否调用了IDataErrorInfo(我假设您正在进行IDataErrorInfo验证) - 下一步
  • 将您的验证模板复制为本地资源到您的ComboBox.Resources中,并检查其是否正常工作

尽管如此,如果您发布您的验证模板、combobox xaml和datacontext,那将是好的。


第一个检查肯定有效,第二个我也认为有效,因为不起作用的组合框下面的文本框看到了模板... - TDaver
我已经将我的进一步研究添加到原始帖子中,但仍然没有运气 :( - TDaver

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