.net - mvc - "La colección de elementos debe estar vacía antes de usar ItemsSource".
entity framework code first tutorial español (15)
Intento que las imágenes se muestren en un WPF ListView con el estilo de un WrapPanel como se describe en este artículo antiguo de ATV Avalon Team: Cómo crear una vista personalizada .
Cuando trato de llenar el ListView con una colección consultada LINQ-to-Entities de los objetos ADO.NET Entity Framework obtengo la siguiente excepción:
Excepción
La colección de elementos debe estar vacía antes de usar ItemsSource.
Mi código…
Visual Basic
Private Sub Window1_Loaded(...) Handles MyBase.Loaded
ListViewImages.ItemsSource = From g In db.Graphic _
Order By g.DateAdded Ascending _
Select g
End Sub
XAML
<ListView Name="ListViewImages"
SelectionMode="Single"
ItemsSource="{Binding}">
<local:ImageView />
</ListView>
Puse un punto de interrupción en esa línea. ListViewImages.ItemsSource
es Nothing
antes de la asignación de LINQ.
Excepción
La colección de elementos debe estar vacía antes de usar ItemsSource.
Esta excepción se produce cuando agrega elementos a ItemsSource
través de diferentes fuentes . Por lo tanto, asegúrese de no haber perdido una etiqueta accidentalmente, haber perdido una etiqueta, haber agregado etiquetas adicionales o haber escrito mal una etiqueta.
<!--Right-->
<ItemsControl ItemsSource="{Binding MyItems}">
<ItemsControl.ItemsPanel.../>
<ItemsControl.MyAttachedProperty.../>
<FrameworkElement.ActualWidth.../>
</ItemsControl>
<!--WRONG-->
<ItemsControl ItemsSource="{Binding MyItems}">
<Grid.../>
<Button.../>
<DataTemplate.../>
<Heigth.../>
</ItemsControl>
Mientras ItemsControl.ItemsSource
ya está configurado mediante ItemsControl.ItemsSource
, otros elementos (Cuadrícula, Botón, ...) no se pueden agregar a la fuente. Sin embargo, mientras ItemsSource
no está en uso , se permite el siguiente código:
<!--Right-->
<ItemsControl>
<Button.../>
<TextBlock.../>
<sys:String.../>
</ItemsControl>
observe la ItemsSource="{Binding MyItems}"
faltante ItemsSource="{Binding MyItems}"
.
¡Cuidado con los errores tipográficos! Tenía lo siguiente
<TreeView ItemsSource="{Binding MyCollection}">
<TreeView.Resources>
...
</TreeView.Resouces>>
</TreeView>
(Observe el seguimiento > , que se interpreta como contenido, por lo que está configurando el doble del contenido ... Me tomó un tiempo :)
El mío era con un estilo de cuadrícula de datos. Si <DataGrid.RowStyle>
etiquetas <DataGrid.RowStyle>
alrededor del Estilo, obtendrá ese problema. Lo extraño es que funcionó por un tiempo así. Aquí está el código malo.
<DataGrid Name="DicsountScheduleItemsDataGrid"
Grid.Column="0"
Grid.Row="2"
AutoGenerateColumns="false"
ItemsSource="{Binding DiscountScheduleItems, Mode=OneWay}">
<Style TargetType="DataGridRow">
<Setter Property="IsSelected"
Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
y lo bueno
<DataGrid Name="DicsountScheduleItemsDataGrid"
Grid.Column="0"
Grid.Row="2"
AutoGenerateColumns="false"
ItemsSource="{Binding DiscountScheduleItems, Mode=OneWay}">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="IsSelected"
Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
</DataGrid.RowStyle>
El motivo por el que se lanza esta excepción particular es que el contenido del elemento se aplica a la colección Elementos de ListView. Por lo tanto, el XAML inicializa el ListView con un solo local: ImageView en su colección Items. Pero cuando se utiliza un control de elementos, debe usar la propiedad Elementos o la propiedad ItemsSource, no puede usar ambos al mismo tiempo. Por lo tanto, cuando se procesa el atributo ItemsSource se lanza una excepción.
Puede averiguar a qué propiedad se aplicará el contenido de un elemento buscando ContentPropertyAttribute en la clase. En este caso, se defined más arriba en la jerarquía de clases, en ItemsControl:
[ContentPropertyAttribute("Items")]
La intención aquí era que la Vista de ListView se establezca en un local: ImageView, por lo que la solución es indicar explícitamente la propiedad que se va a establecer.
Arregle el XAML y la excepción desaparece:
<ListView Name="ListViewImages"
SelectionMode="Single"
ItemsSource="{Binding}">
<ListView.View>
<local:ImageView />
</ListView.View>
</ListView>
Faltaba esa etiqueta <ListView.View>
.
En mi caso, no estaba usando DataTemplate para ItemsControl.
Antiguo:
<ItemsControl Width="243" ItemsSource="{Binding List, Mode=TwoWay}">
<StackPanel Orientation="Horizontal">
<TextBox Width="25" Margin="0,0,5,0" Text="{Binding Path=Property1}"/>
<Label Content="{Binding Path=Property2}"/>
</StackPanel>
</ItemsControl>
Nuevo:
<ItemsControl Width="243" ItemsSource="{Binding List, Mode=TwoWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Width="25" Margin="0,0,5,0" Text="{Binding Path=Property1}"/>
<Label Content="{Binding Path=Property2}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
En mi caso, solo era un StackPanel adicional dentro de ListView:
<ListView Name="_details" Margin="50,0,50,0">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Location.LicenseName, StringFormat=''Location: {0}''}"/>
<TextBlock Text="{Binding Ticket.Employee.s_name, StringFormat=''Served by: {0}''}"/>
<TextBlock Text="{Binding Ticket.dt_create_time, StringFormat=''Started at: {0}''}"/>
<Line StrokeThickness="2" Stroke="Gray" Stretch="Fill" Margin="0,5,0,5" />
<ItemsControl ItemsSource="{Binding Items}"/>
</StackPanel>
</StackPanel>
</ListView>
Se convierte en:
<ListView Name="_details" Margin="50,0,50,0">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Location.LicenseName, StringFormat=''Location: {0}''}"/>
<TextBlock Text="{Binding Ticket.Employee.s_name, StringFormat=''Served by: {0}''}"/>
<TextBlock Text="{Binding Ticket.dt_create_time, StringFormat=''Started at: {0}''}"/>
<Line StrokeThickness="2" Stroke="Gray" Stretch="Fill" Margin="0,5,0,5" />
<ItemsControl ItemsSource="{Binding Items}"/>
</StackPanel>
</ListView>
y todo está bien.
Mantenga la columna de plantilla dentro de DataGrid.Columns. Esto me ayudó a resolver este problema.
Ref: DataGridTemplateColumn: la colección de elementos debe estar vacía antes de usar ItemsSource.
Me encontré con un ejemplo MUY insidioso de este problema. Mi fragmento original era mucho más complejo, lo que dificultaba ver el error.
<ItemsControl
Foreground="Black" Background="White" Grid.IsSharedSizingScope="True"
x:Name="MyGrid" ItemsSource="{Binding}">
>
<ItemsControl.ItemsPanel>
<!-- All is fine here -->
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<!-- All is fine here -->
</ItemsControl.ItemTemplate>
<!-- Have you caught the error yet? -->
</ItemsControl>
¿El bicho? ¡La etiqueta adicional > después de la apertura inicial <ItemsControl>
! El <
se aplicó a la colección de Elementos incorporada. Cuando el DataContext se configuró más tarde, crashola instantáneo. Por lo tanto, tenga cuidado con algo más que los errores que rodean a sus elementos. Controle los datos específicos de los niños al depurar este problema.
Para expresar la respuesta de manera diferente; Verifique que no haya Nodos padre faltantes o nodos incorrectos .
Esto falló:
Sin padre (o padre incorrecto) para el nodo hijo ItemsPanelTemplate
<ItemsControl ItemsSource="{Binding TimeSpanChoices}">
<ItemsPanelTemplate>
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
...
</ItemsControl>
Esto funcionó:
<ItemsControl ItemsSource="{Binding TimeSpanChoices}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
...
</ItemsControl>
Tal vez no sea una respuesta tan útil, pero tuve el mismo problema al cambiar el orden de las columnas y cometí un error como el de la siguiente muestra. Al tener muchas columnas, las reordené y de alguna manera pegué una después de cerrar la etiqueta /DataGrid.Columns
:
<DataGridTemplateColumn x:Name="addedDateColumn" Header="Added Date" Width="SizeToHeader">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=AddedDate}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGridTemplateColumn x:Name="rowguidColumn" Header="rowguid" Width="SizeToHeader">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=rowguid}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid>
De todos modos, perdí media hora debido a esto. Espero que esto ayude a otros.
Tuve este error cuando traté de aplicar menús contextuales a mi TreeView
. Esos intentos terminaron en un XAML malo que se compiló de alguna manera:
<TreeView Height="Auto" MinHeight="100" ItemsSource="{Binding Path=TreeNodes, Mode=TwoWay}"
ContextMenu="{Binding Converter={StaticResource ContextMenuConverter}}">
ContextMenu="">
<TreeView.ItemContainerStyle>
...
Tenga en cuenta la línea problemática: ContextMenu="">
.
No sé por qué compiló, pero pensé que vale la pena mencionar como una razón para este mensaje de excepción críptico. Como dijo Armentage, mira atentamente el XAML, especialmente en los lugares que editaste recientemente.
Tuve este mismo error en un escenario diferente
<ItemsControl ItemsSource="{Binding TableList}">
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl>
La solución fue agregar la etiqueta ItemsControl.ItemsPanel
antes de ItemsPanelTemplate
<ItemsControl ItemsSource="{Binding TableList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Tuve este mismo error por un tiempo en un escenario ligeramente diferente. tuve
<wpftoolkit:DataGrid
AutoGenerateColumns="False"
ItemsSource="{Binding Path=Accounts}" >
<wpftoolkit:DataGridTextColumn
Header="Account Name"
Binding="{Binding Path=AccountName}" />
</wpftoolkit:DataGrid>
que arreglé para ser
<wpftoolkit:DataGrid
AutoGenerateColumns="False"
ItemsSource="{Binding Path=Accounts}" >
<wpftoolkit:DataGrid.Columns>
<wpftoolkit:DataGridTextColumn
Header="Account Name"
Binding="{Binding Path=AccountName}" />
</wpftoolkit:DataGrid.Columns>
</wpftoolkit:DataGrid>
Yo también en un escenario diferente.
<ComboBox Cursor="Hand" DataContext="{Binding}"
FontSize="16" Height="27" ItemsSource="{Binding}"
Name="cbxDamnCombo" SelectedIndex="0" SelectedValuePath="MemberId">
<DataTemplate>
<TextBlock DataContext="{Binding}">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} / {1}">
<Binding Path="MemberName"/>
<Binding Path="Phone"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox>
Ahora cuando completa con la etiqueta faltante Control.ItemTemplate , todo se vuelve normal:
<ComboBox Cursor="Hand" DataContext="{Binding}"
FontSize="16" Height="27" ItemsSource="{Binding}"
Name="cbxDamnCombo" SelectedIndex="0" SelectedValuePath="MemberId">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock DataContext="{Binding}">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} / {1}">
<Binding Path="MemberName"/>
<Binding Path="Phone"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
<ComboBox.ItemTemplate>
</ComboBox>
Yo tenía el mismo error. El problema era este símbolo adicional ">" agregado por error entre las etiquetas </ ComboBox.SelectedValue> y </ ComboBox>:
<ComboBox
ItemsSource="{Binding StatusTypes}"
DisplayMemberPath="StatusName"
SelectedValuePath="StatusID">
<ComboBox.SelectedValue>
<Binding Path="StatusID"/>
</ComboBox.SelectedValue>
>
</ComboBox>
y aquí está el código correcto:
<ComboBox
ItemsSource="{Binding StatusTypes}"
DisplayMemberPath="StatusName"
SelectedValuePath="StatusID">
<ComboBox.SelectedValue>
<Binding Path="StatusID"/>
</ComboBox.SelectedValue>
</ComboBox>