当我选择(通过单击或通过键盘)我的DataGrid上的空白行(当我想添加新行时),出现意外的验证错误(但没有例外) - datagrid的边框变为红色,就像你一样可以在下图中看到。当我在空行上第二次点击时,红色边框消失。其他一切工作正常,新行添加。此外,我没有任何验证规则。当我用空文本创建一行时,值是有效的。
我不希望这种行为和这个红色边框,任何人都知道,为什么会发生这种情况以及如何解决这个问题?某些验证失败的原因和地点?
下面我附上一些源代码:
xaml中的DataGrid定义:
<DataGrid IsSynchronizedWithCurrentItem="True" DisplayMemberPath="Name"
ItemsSource="{Binding Path=ConfigFiles}" SelectedItem="{Binding Path=SelectedConfigFile}"
Grid.Column="1" Height="87" Margin="0,26,11,32" Style="{DynamicResource DataGridStyle}">
<DataGrid.Columns>
<DataGridTextColumn Width="1*" Binding="{Binding Name}" />
</DataGrid.Columns>
</DataGrid>
我的ViewModel的部分:
public class ManageModulesVM : BaseVM // Implements INotifyPropertyChanged
{
// ...
public ObservableCollection<ConfigFile> ConfigFiles
{
get { return selectedModule == null ? null : selectedModule.ConfigFiles; }
set
{
selectedModule.ConfigFiles = value;
OnPropertyChanged(() => ConfigFiles);
}
}
public ConfigFile SelectedConfigFile
{
get { return selectedModule == null ? null : selectedModule.SelectedConfigFile; }
set
{
if (value != null)
{
selectedModule.SelectedConfigFile = value;
}
OnPropertyChanged(() => SelectedConfigFile);
OnPropertyChanged(() => Parameters);
}
}
// ...
}
ConfigFile类:
public class ConfigFile
{
public string Name { get; set; }
public IList<Parameter> Parameters { get; set; }
public ConfigFile() { Name = ""; Parameters = new List<Parameter>(); }
}
编辑: 经过进一步调查后我知道,SelectedItem绑定导致了问题(当我删除此绑定时,验证错误停止显示),但我仍然不知道为什么以及如何解决这个问题。
答案 0 :(得分:21)
我找到了自己的解决方案。我写了一个值转换器并将其绑定到绑定:
(SelectedItem="{Binding Path=SelectedConfigFile,Converter={StaticResource configFileConverter}}")
转换器类:
namespace Converters
{
public class SelectedConfigFileConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value is ConfigFile)
return value;
return null;
}
}
}
在resources.xaml
文件(或任何其他资源位置)中定义资源:
<ResourceDictionary (...) xmlns:conv="clr-namespace:Converters" >
<conv:SelectedConfigFileConverter x:Key="configFileConverter" />
</ResourceDictionary>
此解决方案的优点是SelectedConfigFile
属性的类型没有改变(对于一般的object
类型),因此它仍然是强类型的。
答案 1 :(得分:8)
要了解原因,当您在调试模式下单击DataGrid的新行时,请参阅调试窗口。有第一个异常消息可以让您了解问题发生的原因。
是的,问题来自于类型转换。您需要将SelectedItem的类型修改为对象类型,如下所示。
public class ManageModulesVM : BaseVM // Implements INotifyPropertyChanged
{
// ...
public object SelectedConfigFile
{
get { return selectedModule == null ? null : selectedModule.SelectedConfigFile; }
set
{
if (value != null)
{
selectedModule.SelectedConfigFile = value;
}
OnPropertyChanged(() => SelectedConfigFile);
OnPropertyChanged(() => Parameters);
}
}
// ...
}
答案 2 :(得分:6)
这是一个通用转换器,可以用于任何DataGrid,绑定任何类型的项目:
public class DataGridItemConverter : MarkupExtension, IValueConverter
{
static DataGridItemConverter converter;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (value != null && value.GetType() == targetType) ? value : null;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (converter == null)
converter = new DataGridItemConverter();
return converter;
}
}
由于它实现了MarkupExtension,您甚至不需要定义静态资源,您可以像这样引用它:
SelectedItem="{Binding SelectedThing,Converter={conv:DataGridItemConverter}}"
答案 3 :(得分:3)
您可以将此行添加到DataGrid:
<DataGrid Validation.ErrorTemplate="{x:Null}" />
答案 4 :(得分:0)
您可以将此行添加到DataGrid:
<DataGrid Validation.ErrorTemplate="{x:Null}" />
它将解决问题