“元素已经是另一个元素的子元素”添加到集合时出错
我也有一个带有 Datapager 的 Datagrid/Dataform 设置。我的 DataPager.PageSize 以声明方式设置为 10。所有三个控件的 ItemsSource 都设置为 QueryableCollectionView。如果我的集合中的记录少于 10 条,那么向集合中添加新项目是没有问题的。我单击 DataForm(新项目)中的 + 号,填写表单,捕获 DP 上的 edit_ending 事件,然后保存到我的 SQL DB,没有任何问题。
但是,当我有 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) - 通过 Web 服务正确填充 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 && _selectedWOEquipment.EquipmentCode != null)
{
_selectedWOEquipment.EquipmentDescription = "";
_selectedWOEquipment.EquipmentDescription = EquipmentDescriptionList[EquipmentList.IndexOf(_selectedWOEquipment.EquipmentCode)];
}
}
return _selectedWOEquipment;
}
set
{
_selectedWOEquipment = value;
RaisePropertyChanged("SelectedWOEquipment");
}
}
I've got a Datagrid/Dataform setup with a Datapager as well. My DataPager.PageSize is set declaratively to 10. My ItemsSource for all three controls are set to a QueryableCollectionView. If my collection has less than 10 records, I have no problem adding a new item to the collection. I click the + sign in my DataForm (new item), fill out the forms, capture the edit_ended event on the DP, and save to my SQL DB with no issues.
However, when I have 10+ items, and I click the + sign (new item), the app throws a "Element is already the child of another element" error. I'm not sure which of the two controls (Gridview or DataPager) is causing this problem, and I'm also not sure how to fix it!
Code (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" />
Code (Viewmodel) - WOEquipmentItems properly populated via Web Service:
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 && _selectedWOEquipment.EquipmentCode != null)
{
_selectedWOEquipment.EquipmentDescription = "";
_selectedWOEquipment.EquipmentDescription = EquipmentDescriptionList[EquipmentList.IndexOf(_selectedWOEquipment.EquipmentCode)];
}
}
return _selectedWOEquipment;
}
set
{
_selectedWOEquipment = value;
RaisePropertyChanged("SelectedWOEquipment");
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,解决方案简单得可笑。我添加了以下内容:在我的 ViewModel 中,我注册了此命令,触发了一个“AddingNewItem”函数,该函数仅执行
MyQuerableCollection.MoveToLastPage()
。这迫使我的网格和寻呼机移动到最后一页,这意味着我选择的项目是可见的不抛出错误。编辑添加 - 当我的收藏正好为 10 时,它也抛出一个错误。因此,我进行了一项检查,看看 ItemCount % 10 == 0 是否成立。如果是这样,我删除了列表中的第一项 (Equipment.RemoveAt[0])。因为在设置新项目后,我运行了 LoadData() 函数,所以这不是问题。
Solution turned out to be ridiculously simple. I added this: In my ViewModel, I registered this command, firing off a "AddingNewItem" function that simply executed
MyQuerableCollection.MoveToLastPage()
. This forced my grid & pager to move to the last page, which meant my selected item was visible & not throwing errors.Edit to add - when my collection was exactly at 10, it was throwing an error as well. So I included a check to see if ItemCount % 10 == 0. If so, I removed the first item in the list (Equipment.RemoveAt[0]). Since, after setting the new item, I run my LoadData() function, this wasn't an issue.