我需要做什么,使ContentControl与IDataErrorInfo一起工作,并在选中或取消选中复选框时检查有效性?
一些代码:
捆绑:
<ContentControl Content="{Binding GeneralInvoiceTypes,ValidatesOnDataErrors=True}" Margin="0,5,0" />
数据模板:
<DataTemplate DataType="{x:Type viewmodels:MultipleOptionsviewmodel}"> <GroupBox Header="{Binding Title}"> <ItemsControl ItemsSource="{Binding Options}" /> </GroupBox> </DataTemplate> <DataTemplate DataType="{x:Type viewmodels:Optionviewmodel}"> <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Name}" Margin="6,3,0" /> </DataTemplate>
样式:
<Style TargetType="{x:Type ContentControl}"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="true"> <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self},Path=(Validation.Errors)[0].ErrorContent}" /> </Trigger> </Style.Triggers> <Setter Property="Validation.ErrorTemplate"> <Setter.Value> <ControlTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="90*" /> <ColumnDefinition Width="20" /> </Grid.ColumnDefinitions> <Border BorderBrush="Red" BorderThickness="1" CornerRadius="2.75" Grid.Column="0"> <AdornedElementPlaceholder Grid.Column="0" /> </Border> <TextBlock Foreground="Red" Grid.Column="1" Margin="0" FontSize="12" VerticalAlignment="Center" HorizontalAlignment="Left" x:Name="txtError"> * </TextBlock> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
解决方法
What do I have to do,to make the ContentControl work together with
IDataErrorInfo and check the validity when a check Box is checked or
unchecked?
添加一点Rachels回答.
使用异步数据验证更容易解决此问题,但遗憾的是,这在WPF 4.5 is released之前不可用.
内容绑定到Mainviewmodel中的GeneralInvoiceTypes.由于我们不能进行异步数据验证,因此必须为GeneralInvoiceTypes引发PropertyChanged以进行验证.这可行,但我会采用Rachel建议的方法,并在MultipleOptionsviewmodel中引入另一个名为IsValid的属性
可以从Tag(或附加属性)到GeneralInvoiceTypes.IsValid完成对IsValid的绑定.当在任何选项中更改IsChecked时,我们还必须在MultipleOptionsviewmodel中得到通知.例如,可以通过在CheckBoxes中使用命令绑定来完成此操作.
因此,需要沿着以下几行进行一些更改.
我还上传了一个示例项目,在此实现:https://www.dropbox.com/s/fn8e4n4s68wj3vk/ContentControlValidationTest.zip?dl=0
ContentControl中
<ContentControl Content="{Binding Path=GeneralInvoiceTypes}" Tag="{Binding Path=GeneralInvoiceTypes.IsValid,ValidatesOnDataErrors=True}" />
Optionviewmodel DataTemplate
<DataTemplate DataType="{x:Type viewmodels:Optionviewmodel}"> <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Name}" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContentControl}},Path=DataContext.IsValidCheckCommand}" Margin="6,0" /> </DataTemplate>
MultipleOptionsviewmodel
private ICommand m_isValidCheckCommand; public ICommand IsValidCheckCommand { get { return m_isValidCheckCommand ?? (m_isValidCheckCommand = new RelayCommand(param => IsValidCheck())); } } private void IsValidCheck() { IsValid = CheckIsValid(); } private bool CheckIsValid() { foreach (Optionviewmodel option in Options) { if (option.IsChecked == true) { return true; } } return false; } private bool m_isValid; public bool IsValid { get { return m_isValid; } set { m_isValid = value; OnPropertyChanged("IsValid"); } } public string this[string columnName] { get { if (columnName == "IsValid") { if (IsValid == false) { return "At least 1 Option must be selected"; } } return string.Empty; } }