【发布时间】:2016-07-11 12:30:02
【问题描述】:
我第一次尝试在 XAML / WPF 中实现数据验证。我已经阅读了几个教程,似乎有多种方法可以做到这一点。我已经确定了一种方法,但它不起作用。
首先,这是我希望错误显示的理想方式(在ComboBox 上方 和Label 的右侧)。如果可以的话……
我创建了一个ValidationRule:
using System;
using System.Globalization;
using System.Windows.Controls;
namespace OCLMEditor.ValidationRules
{
class StudyPointValidationRule : ValidationRule
{
public bool BibleReading { get; set; }
public StudyPointValidationRule()
{
BibleReading = false;
}
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if(value == null)
return new ValidationResult(false, "The study point has not been set.");
int iStudy = (int)value;
if(BibleReading)
{
if(iStudy > 17)
return new ValidationResult(false, "Maximum study point for bible readings is 17.");
}
else
{
if(iStudy == 7 || iStudy > 51)
return new ValidationResult(false, "Study points 7, 52 and 53 are not permitted for student items.");
}
return new ValidationResult(true, null);
}
}
}
然后,我将其添加到 XAML 中的 Window 类中:
xmlns:ValidationRules="clr-namespace:OCLMEditor.ValidationRules":
在Window.Resources:
<ControlTemplate x:Key="StudyPointValidationTemplate">
<DockPanel>
<TextBlock Foreground="Red" FontSize="20">!</TextBlock>
<AdornedElementPlaceholder/>
</DockPanel>
</ControlTemplate>
然后,对于我希望应用此验证的第一个 ComboBox,我将其更改为:
<ComboBox DataContext="{Binding DataContext, ElementName=oclmEditor}"
ItemsSource="{Binding ReadingStudyPointsList}"
ItemContainerStyle="{StaticResource StudyPointComboBoxStyle}"
ItemTemplate="{StaticResource StudyPointComboItem}"
Validation.ErrorTemplate="{StaticResource StudyPointValidationTemplate}"
Tag="{Binding Meeting.BibleReadingMainName, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding Meeting.BibleReadingMainStudyPoint, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Number"/>
收件人:
<ComboBox DataContext="{Binding DataContext, ElementName=oclmEditor}"
ItemsSource="{Binding ReadingStudyPointsList}"
ItemContainerStyle="{StaticResource StudyPointComboBoxStyle}"
ItemTemplate="{StaticResource StudyPointComboItem}"
Validation.ErrorTemplate="{StaticResource StudyPointValidationTemplate}"
Tag="{Binding Meeting.BibleReadingMainName, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding Meeting.BibleReadingMainStudyPoint, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
>
<ComboBox.SelectedValuePath>
<Binding Path="Number">
<Binding.ValidationRules>
<ValidationRules:StudyPointValidationRule BibleReading="True"/>
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedValuePath>
</ComboBox>
我收到此错误:
System.Windows.Data 错误:40:BindingExpression 路径错误:在“对象”“OCLMEditorViewModel”(HashCode=17586541)上找不到“数字”属性。绑定表达式:路径=数字; DataItem='OCLMEditorViewModel' (HashCode=17586541);目标元素是 'ComboBox' (Name='');目标属性是“SelectedValuePath”(类型“字符串”)
我不明白为什么,因为我以前可以使用“数字”。
更新
如果值太高,我已扩展我的模型数据类以引发异常。例如:
[XmlIgnore]
public int BibleReadingMainStudyPoint
{
get { return _TFGW.BibleReadingItem.Main.StudyPoint; }
set
{
if (value > 17)
throw new ArgumentOutOfRangeException("Maximum Bible reading study point is 17.");
_TFGW.BibleReadingItem.Main.StudyPoint = value;
MarkDirty();
OnPropertyChanged("BibleReadingMainStudyPoint");
}
}
我肯定会抛出异常:
参数名称:最大读经点数为17。 在 OCLMEditor.Data.MeetingInfo.Meeting.set_BibleReadingMainStudyPoint(Int32 值) 在 D:\My Programs\OCLMEditor\OCLMEditor\Data\MeetingInfo\Meeting.cs:line 234 在 D:\My Programs\OCLMEditor\OCLMEditor\ViewModels\OCLMEditorViewModel.cs:line 184' 中的 OCLMEditor.OCLMEditorViewModel.set_SelectedStudentItem(学生值)处
我更改了 XAMl,因为 ValidationRule 不适用于这种情况:
<Binding.ValidationRules>
<ExceptionValidationRule/>
</Binding.ValidationRules>
所以我期待它现在可以直观地显示错误。屏幕上什么都没有。
资源:
<Window.Resources>
<ValueConverters:StudyPointWorkingOn x:Key="StudyPointWorkingOn" />
<Style x:Key="StudyPointComboBoxStyle" TargetType="ComboBoxItem">
<Setter Property="Tag" Value="{Binding Number}" />
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource StudyPointWorkingOn}">
<Binding RelativeSource="{RelativeSource Self}" Path="Tag"/>
<Binding Path="DataContext" ElementName="oclmEditor" UpdateSourceTrigger="PropertyChanged" />
<Binding Path="Tag" RelativeSource="{RelativeSource AncestorType=ComboBox}"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate x:Key="StudyPointComboItem">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Number}"/>
<TextBlock Text=" - "/>
<TextBlock Text="{Binding Title}"/>
</StackPanel>
</DataTemplate>
<ControlTemplate x:Key="StudyPointValidationTemplate">
<DockPanel>
<TextBlock Foreground="Red" FontSize="20">!</TextBlock>
<AdornedElementPlaceholder/>
</DockPanel>
</ControlTemplate>
</Window.Resources>
更新 2
我可以看出屏幕上有一个验证符号。但它并没有减少组合的宽度,所以它可以被看到。
【问题讨论】:
-
你能确认一下,你的
OCLMEditorViewModel有一个数字属性吗? -
@lokusking 不,它没有。 Number 属性是 ComboBoxItem 对象的一部分。您可以在有效的代码中看到 SelectedValue/Path 是什么。
-
你不能那样设置 SelectedValuePath 因为它是一个字符串。它存储用于从 SelectedItem 获取 SelectedValue 的路径
-
@CiccioRocca 如果我将
SelectedValuePath移回原来的位置,我该如何告诉它这样做Validation? -
@AndrewTruckle 您可以直接在组合框所选项目上进行操作。
标签: c# wpf validation xaml combobox