我有一个 ViewModel,它表示多个选项并实现 IDataErrorInfo
。仅当至少选择了这些选项之一时,此 ViewModel 才有效。它绑定(bind)到 ContentControl
。 DataTemplate
用于将 ViewModel 可视化为包含 ItemsControl
的 GroupBox
。另一个 DataTemplate
将每个选项可视化为一个 CheckBox
。
我必须做什么,才能使 ContentControl
与 IDataErrorInfo
一起工作,并在选中或取消选中复选框时检查有效性?
部分代码:
绑定(bind):
<ContentControl Content="{Binding GeneralInvoiceTypes, ValidatesOnDataErrors=True}"
Margin="0,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,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 之前不可用。 .
Content
绑定(bind)到 MainViewModel
中的 GeneralInvoiceTypes
。由于我们无法执行异步数据验证,因此必须为 GeneralInvoiceTypes
引发 PropertyChanged
才能进行验证。这可行,但我会采用 Rachel 建议的方法,并在 MultipleOptionsViewModel
IsValid
的属性
到 IsValid
的绑定(bind)可以从 Tag
(或附加属性)到 GeneralInvoiceTypes.IsValid
完成。当任何 Options
中的 IsChecked
发生更改时,我们还必须在 MultipleOptionsViewModel 中收到通知。例如,这可以通过在 CheckBoxes
中使用命令绑定(bind)来完成。
因此需要按照以下几行进行一些更改。
我还上传了一个示例项目,这里实现了这个: https://www.dropbox.com/s/fn8e4n4s68wj3vk/ContentControlValidationTest.zip?dl=0
内容控件
<ContentControl Content="{Binding Path=GeneralInvoiceTypes}"
Tag="{Binding Path=GeneralInvoiceTypes.IsValid,
ValidatesOnDataErrors=True}" />
OptionViewModel 数据模板
<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,3,3,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;
}
}
关于c# - ContentControl 中的 GroupBox - 支持由绑定(bind)到 ContentControl 的内容实现的 IDataErrorInfo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7876103/