Ошибка «Элемент уже является дочерним по отношению к другому элементу» при добавлении в коллекцию

#c# #silverlight #gridview #dataform #datapager

#c# #silverlight #gridview #форма данных #datapager

Вопрос:

У меня также есть настройка Datagrid / Dataform с помощью Datapager. Мой DataPager.Размер страницы декларативно устанавливается равным 10. Мой ItemsSource для всех трех элементов управления настроен на QueryableCollectionView. Если в моей коллекции меньше 10 записей, у меня не возникнет проблем с добавлением нового элемента в коллекцию. Я нажимаю знак в своей форме данных (новый элемент), заполняю формы, фиксирую событие edit_ended в DP и сохраняю в своей базе данных SQL без проблем.

Однако, когда у меня есть более 10 элементов, и я нажимаю знак (новый элемент), приложение выдает ошибку «Элемент уже является дочерним элементом другого элемента». Я не уверен, какой из двух элементов управления (Gridview или DataPager) вызывает эту проблему, и я также не уверен, как это исправить!

Код (Xaml):

 <toolkit:DataForm x:Name="dataForm" 
    Width="{Binding Width, ElementName=GV1}" 
    CurrentItem="{Binding SelectedWOEquipment}" 
    ItemsSource="{Binding WOEquipmentItems}"
    AutoEdit="False" 
    Tag="Equipment"
Header="Add/Update Equipment"
    AutoCommit="False" 
    Margin="0,0,0,10" >
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="EditEnded">
            <cmd:EventToCommand Command="{Binding SaveEquipmentCommand}" PassEventArgsToCommand="True"/>
        </i:EventTrigger>
        <i:EventTrigger EventName="DeletingItem">
            <cmd:EventToCommand Command="{Binding DeleteCommand}"
                CommandParameter="{Binding Tag, ElementName=dataForm}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <toolkit:DataForm.ReadOnlyTemplate>
        <DataTemplate>
            <StackPanel>
                <toolkit:DataField>
                    <TextBox Text="{Binding EquipmentCode}" />
                </toolkit:DataField>
                <toolkit:DataField Label="Equipment Description">
                    <TextBox Text="{Binding EquipmentDescription}" />
                </toolkit:DataField>
                <toolkit:DataField Label="Hours">
                    <TextBox IsEnabled="False" Text="{Binding Hours}" />
                </toolkit:DataField>
            </StackPanel>
        </DataTemplate>
    </toolkit:DataForm.ReadOnlyTemplate>
    <toolkit:DataForm.EditTemplate>
        <DataTemplate>
            <StackPanel>
                <toolkit:DataField Label="Equipment Codes">
                    <TextBox Text="{Binding EquipmentCode}" />
                </toolkit:DataField>
                <toolkit:DataField Label="Equipment Description">
                    <TextBox IsEnabled="False"
             Text="{Binding EquipmentDescription}" />
                </toolkit:DataField>
                <toolkit:DataField Label="Hours">
                    <TextBox Text="{Binding Hours, Mode=TwoWay}" />
                </toolkit:DataField>
            </StackPanel>
        </DataTemplate>
    </toolkit:DataForm.EditTemplate>
    <toolkit:DataForm.NewItemTemplate>
        <DataTemplate>
            <StackPanel>
                <toolkit:DataField Label="Equipment Codes">
                    <telerik:RadComboBox x:Name="cboEquipment"
            ItemsSource="{Binding DataSource.EquipmentList, Source={StaticResource DataContextProxy}}"  
                        SelectedValue="{Binding EquipmentCode, Mode=TwoWay}"
                        Margin="0 0 20 0">                                    
                        <telerik:RadComboBox.ItemsPanel>
                            <ItemsPanelTemplate>
                                <VirtualizingStackPanel/>
                            </ItemsPanelTemplate>
                        </telerik:RadComboBox.ItemsPanel>
                    </telerik:RadComboBox>
                </toolkit:DataField>
                <toolkit:DataField Visibility="Collapsed">
                    <TextBox Text="{Binding EquipmentDescription,Mode=TwoWay}" />
                </toolkit:DataField>
                <toolkit:DataField Label="Hours">
                    <TextBox Text="{Binding Hours,Mode=TwoWay}" />
                </toolkit:DataField>
            </StackPanel>
        </DataTemplate>
    </toolkit:DataForm.NewItemTemplate>
 </toolkit:DataForm>
 <Grid>
     <Grid.RowDefinitions>
         <RowDefinition Height="Auto" />
         <RowDefinition Height="*" />
     </Grid.RowDefinitions>
     <telerik:RadGridView ItemsSource="{Binding WOEquipmentItems}"
         x:Name="GV1"
         ShowGroupPanel="False"
         DataLoadMode="Asynchronous"
         HorizontalAlignment="Left"
         HeaderRowStyle="{StaticResource CSAgvHeaderRowStyle}"
         SelectedItem="{Binding SelectedWOEquipment, Mode=TwoWay}"
         AutoGenerateColumns="False" 
         IsReadOnly="True">
             <telerik:RadGridView.Columns>
                 <telerik:GridViewDataColumn DataMemberBinding="{Binding EquipmentCode}" HeaderCellStyle="{StaticResource CSAgvHeaderCellStyle}" Header="Equipment ID" Width="100"/>
                 <telerik:GridViewDataColumn DataMemberBinding="{Binding EquipmentDescription}" HeaderCellStyle="{StaticResource CSAgvHeaderCellStyle}" Header="Description" Width="300"/>
                 <telerik:GridViewDataColumn DataMemberBinding="{Binding Hours}" HeaderCellStyle="{StaticResource CSAgvHeaderCellStyle}" Header="Hours" Width="75"/>
             </telerik:RadGridView.Columns>
             <i:Interaction.Triggers>
                 <i:EventTrigger EventName="SelectedCellsChanged">
                     <cmd:EventToCommand Command="{Binding EditEquipmentCommand}"/>
                 </i:EventTrigger>
              </i:Interaction.Triggers>
          </telerik:RadGridView>
          <sdk:DataPager Grid.Row="1" Source="{Binding WOEquipmentItems}"  PageSize="10" />
  

Код (Viewmodel) — WOEquipmentItems, правильно заполненный через веб-службу:

 private QueryableCollectionView _WOEquipmentItems;
private TSMVVM.Model.WOEquipment _selectedWOEquipment = new TSMVVM.Model.WOEquipment();
public QueryableCollectionView WOEquipmentItems
    {
        get { return _WOEquipmentItems; }
        set
        {
            _WOEquipmentItems = value;
            RaisePropertyChanged("WOEquipmentItems");
        }
    }
public TSMVVM.Model.WOEquipment SelectedWOEquipment
    {
        get 
        {
            if (_selectedWOEquipment != null)
            {
                if (_selectedWOEquipment.EquipmentDescription == null amp;amp; _selectedWOEquipment.EquipmentCode != null)
                {
                    _selectedWOEquipment.EquipmentDescription = "";
                    _selectedWOEquipment.EquipmentDescription = EquipmentDescriptionList[EquipmentList.IndexOf(_selectedWOEquipment.EquipmentCode)];
                }
            }
            return _selectedWOEquipment; 
        }
        set
        {
            _selectedWOEquipment = value;
            RaisePropertyChanged("SelectedWOEquipment");
        }
    }
  

Комментарии:

1. Взгляните на этот пост и посмотрите, может ли это помочь вам хотя бы отследить источник. whydoidoit.com/2010/08/30 /…

2. Спасибо Nissan. Я мог бы добавить это (возможно, должен был) в свой пост. Я уже запустил это через его XAMLValidator, и это не приводит к сбою. 🙁 Хотя спасибо.

Ответ №1:

Решение оказалось до смешного простым. Я добавил это: В моей ViewModel я зарегистрировал эту команду, запустив функцию «AddingNewItem», которая просто выполнялась MyQuerableCollection.MoveToLastPage() . Это заставило мою сетку и пейджер переместиться на последнюю страницу, что означало, что выбранный мной элемент был виден и не выдавал ошибок.

Редактировать, чтобы добавить — когда моя коллекция была ровно в 10, она также выдавала ошибку. Поэтому я включил проверку, чтобы увидеть, является ли ItemCount% 10 == 0. Если это так, я удалил первый элемент в списке (Equipment.RemoveAt[0]). Поскольку после установки нового элемента я запускаю свою функцию loadData (), это не было проблемой.