Hello其他程序员。我在使用IDataErrorInfo的Silverlight MVVM模式上遇到了这个奇怪的问题。这是我在StackOverflow中提出的第一个问题,所以我希望我能够正确地解释它。这是交易:
我有一个巨大的Job Register ChildWindow,它有一些控件只有在选中一个名为HasPrevision的复选框时才能启用。这个想法是:如果作业有Prevision,那么与预设相关的所有控件都是Enabled,否则它们是Disabled。 现在,如果有预设,用户必须在PrevisionType ComboBox中选择Prevision Type。因此,如果HasPrevision复选框是CHECKED,则必须选择PrevisionType,但如果HasPrevision复选框未选中,则可以取消选中PrevisionType组合框。
以下是这些控件的XAML(我不会在这里显示所有xaml,因为它相当大,但我相信只需显示这些行就可以解决问题):
<!-- The HasPrevision CheckBox -->
<CheckBox Grid.Column="1"
Grid.Row="3"
x:Name="cbxHasPrevision"
IsChecked="{Binding SelectedJob.HasPrevision, Mode=TwoWay}"
Margin="0,20,2,0" />
<!-- The PrevisionType ComboBox -->
<telerik:RadComboBox Grid.Column="1"
Grid.Row="4"
x:Name="cmbPrevisionType"
IsEnabled="{Binding HasPrevision, Converter={StaticResource ControlesCadastroProcessoConverter}, ConverterParameter=IsEnabled}"
ItemsSource="{Binding PrevisionTypeList, Mode=OneWay}"
SelectedItem="{Binding SelectedJob.PrevisionType , Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, ValidatesOnNotifyDataErrors=True}"
Margin="0,4,48,4"
Height="22"
DisplayMemberPath="DsPrevisionType"/>
因此,正如您所看到的,HasPrevision和PrevisionType属性绑定到我的ViewModel中名为SelectedJob的属性。 SelectedJob是一个Job对象。我想要做的就是使用Job Class中的IDataErrorInfo接口来识别是否选择了PrevisionType。现在,如果HasPrevision属性为“true”,我只能要求PrevisionType,所以我的作业类有IDataErrorInfo的代码:
public string this[string columnName]
{
get
{
switch (columnName)
{
case "PrevisionType":
if (HasPrevision && (PrevisionType== null))
return "Select a PrevisionType";
break;
}
return null;
}
这对我来说听起来很合乎逻辑。当我调试代码时,它实际上工作:switch标识columnName,它输入大小写“PrevisionType”,它实际上运行If语句中返回错误消息的返回代码,而不是默认的“return null”子句。但错误消息不显示错误!更糟糕的是:组合框不会自动验证事件。 单击“保存”按钮时,我检查错误并将PrevisionType组合框设置为InvalidFocused状态。组合框在其周围获得红色边框,表示它处于错误状态,但错误消息为空。当我将鼠标悬停在控件上时,会出现一个空的小红框,上面没有任何内容。
更奇怪的是:如果我从IF语句中删除“HasPrevision”检查,保留代码如下,则显示消息并自动验证控件!!!
public string this[string columnName]
{
get
{
switch (columnName)
{
case "PrevisionType":
if (PrevisionType== null)
return "Select a PrevisionType";
break;
}
return null;
}
}
我能想到的一切是,因为我试图根据另一个属性值验证属性,在集合中间的某个位置并且得到Silverlight环境变得“混乱”了?我不知道,我一直试图找到一个解决方案2天没有成功。 以下是我认为相关的其他一些代码。
我的工作类中的属性:
private bool _HasPrevision;
[DataMember]
public bool HasPrevision
{
get { return _HasPrevision; }
set
{
_HasPrevision= value;
RaisePropertyChanged("HasPrevision");
}
}
private PrevisionType.PrevisionType _PrevisionType { get; set; }
[DataMember]
public PrevisionType.PrevisionType PrevisionType
{
get { return _PrevisionType; }
set
{
_PrevisionType = value;
RaisePropertyChanged("PrevisionType");
}
}
我的ViewModel中的My SelectedJob属性是:
public const string SelectedJobPropertyName = "SelectedJob";
private Objects.Register.Job.Job _SelectedJob = null;
public Objects.Register.Job.Job SelectedJob
{
get
{
return _SelectedJob;
}
set
{
if (_SelectedJob == value)
return;
var oldValue = _SelectedJob;
_SelectedJob = value;
RaisePropertyChanged(SelectedJobPropertyName , oldValue, value, true);
}
}
我的保存按钮代码是:
[...]
if(SelectedJob["PrevisionType"] != null)
{
VisualStateManager.GoToState(cmbPrevisionTypeControl, "InvalidFocused", true);
return;
}
[...]
提前致谢,如果我对解释这一点感到有些困惑,我很抱歉。
编辑1:我已经在这里读过这些问题了,但是他们对我没有帮助:
IDataErrorInfo - not seeing any error message even though one gets picked up
Silverlight IDataErrorInfo message does not show in custom control's textbox
答案 0 :(得分:0)
我正在以类似的方式使用Telerik RadComboBox,我没有遇到显示错误消息的问题。这是我的XAML供您参考,希望这有帮助...
<TextBlock Text="Select a User to Assign the Current Step To:" Grid.Row="3" Visibility="{Binding ShowAssigneeUser}"/>
<telerik:RadComboBox x:Name="cmbAllActiveCrmUsers"
IsEditable="True"
Grid.Row="4"
telerik:TextSearch.TextPath="FullName"
Text="{Binding FullName, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"
VerticalAlignment="Center"
Visibility="{Binding ShowAssigneeUser}"
ItemsSource="{Binding AllActiveCrmUsersExceptCurrentUser}"
SelectedIndex="{Binding DefaultAssigneeUserIndex, Mode=TwoWay}"
ItemTemplate="{StaticResource ComboBoxMultilineTemplate}"
Style="{StaticResource ComboBoxStyle}"
Command="{Binding AssignUserChangeCommand}"
CommandParameter="{Binding SelectedIndex, ElementName=cmbAllActiveCrmUsers}"
>
<telerik:RadComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</telerik:RadComboBox.ItemsPanel>
</telerik:RadComboBox>