C# 组合框SelectedValuePath验证不起作用
我第一次尝试在XAML/WPF中实现数据验证。我读过几本教程,似乎有多种方法可以做到这一点。我已经确定了一种方法,但它不起作用 首先,这是我理想的错误显示方式(C# 组合框SelectedValuePath验证不起作用,c#,wpf,validation,xaml,combobox,C#,Wpf,Validation,Xaml,Combobox,我第一次尝试在XAML/WPF中实现数据验证。我读过几本教程,似乎有多种方法可以做到这一点。我已经确定了一种方法,但它不起作用 首先,这是我理想的错误显示方式(组合框上方的和标签右侧的)。如果可能的话 我创建了一个验证规则: using System; using System.Globalization; using System.Windows.Controls; namespace OCLMEditor.ValidationRules { class StudyPointVal
组合框上方的和标签右侧的)。如果可能的话
我创建了一个验证规则
:
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中的窗口类中:
xmlns:ValidationRules="clr-namespace:OCLMEditor.ValidationRules":
在窗口中。参考资料
:
<ControlTemplate x:Key="StudyPointValidationTemplate">
<DockPanel>
<TextBlock Foreground="Red" FontSize="20">!</TextBlock>
<AdornedElementPlaceholder/>
</DockPanel>
</ControlTemplate>
我肯定会抛出异常:
参数名称:最大读经学习点为17。
在OCLMEditor.Data.MeetingInfo.Meeting.set_BibleReadingMainStudyPoint(Int32值)中的D:\My Programs\OCLMEditor\OCLMEditor\Data\MeetingInfo\Meeting.cs:第234行
在OCLMEditor.OCLMEditorViewModel.set_SelectedStudentItem(学生值)中的D:\My Programs\OCLMEditor\OCLMEditor\ViewModels\OCLMEditorViewModel.cs:第184行
我更改了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
我只能看出屏幕上有一个验证符号。但它并没有缩小组合的宽度,以便可以看到它。。它告诉组合框所选数据项的哪个值要分配给SelectedValue
属性。没有什么可以证实的;这不是告诉您用户选择了什么的属性。当选择更改时,它不应该更改,因为Number
始终是要用于SelectedValue
的属性(除非您更改组合框中的项目类型,但这不是您要做的)
要与验证绑定的属性是SelectedValue
,这是问题中的一个属性
<ComboBox
...other properties...
SelectedValuePath="Number"
>
<ComboBox.SelectedValue>
<Binding
Path="Meeting.BibleReadingMainStudyPoint"
Mode="TwoWay"
UpdateSourceTrigger="PropertyChanged"
>
<Binding.ValidationRules>
<ValidationRules:StudyPointValidationRule BibleReading="True"/>
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedValue>
<ComboBox.Style>
<Style
TargetType="ComboBox"
BasedOn="{StaticResource {x:Type ComboBox}}"
>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter
Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
。它告诉组合框所选数据项的哪个值要分配给SelectedValue
属性。没有什么可以证实的;这不是告诉您用户选择了什么的属性。当选择更改时,它不应该更改,因为Number
始终是要用于SelectedValue
的属性(除非您更改组合框中的项目类型,但这不是您要做的)
要与验证绑定的属性是SelectedValue
,这是问题中的一个属性
<ComboBox
...other properties...
SelectedValuePath="Number"
>
<ComboBox.SelectedValue>
<Binding
Path="Meeting.BibleReadingMainStudyPoint"
Mode="TwoWay"
UpdateSourceTrigger="PropertyChanged"
>
<Binding.ValidationRules>
<ValidationRules:StudyPointValidationRule BibleReading="True"/>
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedValue>
<ComboBox.Style>
<Style
TargetType="ComboBox"
BasedOn="{StaticResource {x:Type ComboBox}}"
>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter
Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
如果要实现验证,应执行以下操作:
<ComboBox SelectedValuePath="Number" 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.SelectedValue>
<Binding Path="Meeting.BibleReadingMainName" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
<Binding.ValidationRules>
<ValidationRules:StudyPointValidationRule BibleReading="True"/>
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedValue>
</ComboBox>
使用SelectedValuePath仅用于告知使用哪个属性从SelectedItem获取SelectedValue。如果要实现验证,应执行以下操作:
<ComboBox SelectedValuePath="Number" 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.SelectedValue>
<Binding Path="Meeting.BibleReadingMainName" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
<Binding.ValidationRules>
<ValidationRules:StudyPointValidationRule BibleReading="True"/>
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedValue>
</ComboBox>
使用SelectedValuePath只是为了告诉您使用哪个属性从SelectedItem获取SelectedValue。您可以确认,您的OCLMEditorViewModel
有一个数字属性吗?@lokusking否它没有。Number属性是ComboBoxItem对象的一部分。您可以在运行的代码中看到SelectedValue/路径是什么。您不能这样设置SelectedValuePath,因为它是一个字符串。它存储用于从中获取SelectedValue的路径SelectedItem@CiccioRocca如果我将SelectedValuePath
移回它当时所在的位置,我如何告诉它执行验证
,您的OCLMEditorViewModel
有数字属性吗?@lokusking没有。Number属性是ComboBoxItem对象的一部分。您可以在运行的代码中看到SelectedValue/路径是什么。您不能这样设置SelectedValuePath,因为它是一个字符串。它存储用于从中获取SelectedValue的路径SelectedItem@CiccioRocca如果我将SelectedValuePath
移回它当时所在的位置,我如何告诉它执行验证
?@andrewruckle您可以直接在组合框所选项目上执行。谢谢。由于某种原因,虽然此验证规则似乎仅在我关闭应用程序时触发(我让它执行手动源代码更新)。当SelectedValue更改时,应该进行验证。@当您将验证应用于SelectedValuePath
,或SelectedValue
?当开会时,会出现这种情况。在我的代码中更改BibleReadingMainStudyPoint
时,ComboValue会得到修改。由于该值为25,我希望它得到验证并显示某种错误,而不仅仅是显示组合列表中的空选择。@AndrewTruckle当Sou
<ComboBox SelectedValuePath="Number" 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.SelectedValue>
<Binding Path="Meeting.BibleReadingMainName" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
<Binding.ValidationRules>
<ValidationRules:StudyPointValidationRule BibleReading="True"/>
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedValue>
</ComboBox>