选择Datagrid WPF时,获取错误23和错误7

Des*_*erp 7 .net c# wpf datagrid mvvm

在WPf,C#中工作并使用MVVM-C我在VS的立即窗口中出现以下错误.

我正在谈论的窗口充满了一些文本框和数据网格,用户可以在其中添加新行.填写文本框时,不会显示任何问题.由于这个问题,我无法保存更改.实际上,"保存"按钮不起作用.

但是,只要我点击空数据网格以便能够添加一些数据,我就会在即时窗口中收到以下错误:

System.Windows.Data Error: 23 : Cannot convert '{NewItemPlaceholder}' from type 'NamedObject' to type 'LIMS.ViewModels.ComponentViewModel' for 'en-US' culture with default conversions; consider using Converter property of Binding. NotSupportedException:'System.NotSupportedException: TypeConverter kan niet van MS.Internal.NamedObject worden geconverteerd.
- bij System.ComponentModel.TypeConverter.GetConvertFromException(Object value)
- bij System.ComponentModel.TypeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
- bij MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)'

System.Windows.Data Error: 7 : ConvertBack cannot convert value '{NewItemPlaceholder}' (type 'NamedObject'). BindingExpression:Path=SelectedTestConfiguration.SelectedComponent; DataItem='TestConfigurationsPageViewModel' (HashCode=64210551); target element is 'DataGrid' (Name=''); target property is 'SelectedItem' (type 'Object') NotSupportedException:'System.NotSupportedException: TypeConverter kan niet van MS.Internal.NamedObject worden geconverteerd.
- bij MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)
- bij MS.Internal.Data.ObjectTargetConverter.ConvertBack(Object o, Type type, Object parameter, CultureInfo culture)
- bij System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverter converter, Object value, Type sourceType, Object parameter, CultureInfo culture)'
Run Code Online (Sandbox Code Playgroud)

该程序的屏幕截图:

屏幕

每个页面都存在一个

  • 的PageController
  • PageViewModel
  • PageResources(xaml-代码)

有任何想法吗?我也不知道您需要哪些代码才能看到问题的根源.

Xaml代码的摘录:

<DataTemplate x:Key="TestConfigurationsDataTemplate"
          DataType="{x:Type testconfigurations:TestConfigurationsPageViewModel}">

    <Grid Grid.Row="3"
          Grid.Column="1">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBlock Text="Components" Style="{StaticResource RegularTextLeft}"/>
        <DataGrid Grid.Row="1"
              ItemsSource="{Binding SelectedTestConfiguration.Components}"
              SelectedItem="{Binding SelectedTestConfiguration.SelectedComponent}"
              AutoGenerateColumns="False"
              CanUserAddRows="True"
              Margin="{StaticResource SmallMargin}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <DataGridTextColumn Header="Cell" Binding="{Binding Cell}"/>
                <DataGridCheckBoxColumn Header="PerformCalculation" Binding="{Binding PerformCalculation}"/>
                <DataGridTextColumn Header="Calculation" Binding="{Binding Calculation}"/>
                <DataGridCheckBoxColumn Header="Input Result" Binding="{Binding InputResult}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>


    <Button Grid.Row="5"
            Grid.Column="2"
            Content="Save TestConfiguration"
            Command="{Binding SaveTestConfigurationCommand}"/>
Run Code Online (Sandbox Code Playgroud)

PageViewModel的摘录

public class TestConfigurationsPageViewModel:PageViewModel
{
    private Command _searchCommand;
    public Command SearchCommand
    {
        get { return _searchCommand; }
        set
        {
            if (_searchCommand != value)
            {
                _searchCommand = value;
                RaisePropertyChanged(() => SearchCommand);
            }
        }
    }

    private Command _addTestConfigurationCommand;
    public Command AddTestConfigurationCommand
    {
        get { return _addTestConfigurationCommand; }
        set
        {
            if (_addTestConfigurationCommand != value)
            {
                _addTestConfigurationCommand = value;
                RaisePropertyChanged(() => AddTestConfigurationCommand);
            }
        }
    }

    private Command _saveTestConfigurationCommand;
    public Command SaveTestConfigurationCommand
    {
        get { return _saveTestConfigurationCommand; }
        set
        {
            if (_saveTestConfigurationCommand != value)
            {
                _saveTestConfigurationCommand = value;
                RaisePropertyChanged(() => SaveTestConfigurationCommand);
            }
        }
    }

    private ObservableItemsCollection<TestConfigurationViewModel> _testconfigurations;
    public ObservableItemsCollection<TestConfigurationViewModel> Testconfigurations
    {
        get { return _testconfigurations; }
        set
        {
            if (_testconfigurations != value)
            {
                _testconfigurations = value;
                RaisePropertyChanged(() => Testconfigurations);
            }
        }
    }

    private TestConfigurationViewModel _selectedTestConfiguration;
    public TestConfigurationViewModel SelectedTestConfiguration
    {
        get { return _selectedTestConfiguration; }
        set
        {
            if (_selectedTestConfiguration != value)
            {
                RaisePropertyChanging(() => SelectedTestConfiguration);
                _selectedTestConfiguration = value;
                RaisePropertyChanged(() => SelectedTestConfiguration);
            }
        }
    }

    private string _searchExpression;
    public string SearchExpression
    {
        get { return _searchExpression; }
        set
        {
            if (_searchExpression != value)
            {
                _searchExpression = value;
                RaisePropertyChanged(() => SearchExpression);
            }
        }
    }

    public TestConfigurationsPageViewModel()
    {
        Testconfigurations = new ObservableItemsCollection<TestConfigurationViewModel>();
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 0

这个答案归功于https://www.codeproject.com/Articles/42548/MVVM-and-the-WPF-DataGrid,但这里是关于您的观察的摘要。

问题是您的 DataGrid 将 CanUserAddRows 设置为 True 并且 SelectedItem 绑定到 VM 的某些非字符串属性。新的空行的内部字符串值为“{NewItemPlaceHolder}”。这样就不适合在一起了 解决方法是放置一个适当的占位符来负责,如下所示:

<Window.Resources>
    <converters:IgnoreNewItemPlaceHolderConverter x:Key="IgnoreNewItemPlaceHolderConverter" />
</Window.Resources>
...
<DataGrid CanUserAddRows="True" ItemsSource="{Binding MyItemsSource, UpdateSourceTrigger="PropertyChanged}">
    <DataGrid.SelectedItem>
        <Binding Converter="{StaticResource IgnoreNewItemPlaceHolderConverter}" Path="MySelectedItem" UpdateSourceTrigger="PropertyChanged"/>
    </DataGrid.SelectedItem>
    ...
</DataGrid>
Run Code Online (Sandbox Code Playgroud)

internal class IgnoreNewItemPlaceHolderConverter : IValueConverter
{
    private const string NewItemPlaceholderName = "{NewItemPlaceholder}";
    [ExcludeFromCodeCoverage]
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null && value.ToString() == NewItemPlaceholderName)
            return DependencyProperty.UnsetValue;
        return value;
    }
}
Run Code Online (Sandbox Code Playgroud)