"A coleção de itens deve estar vazia antes de usar o ItemsSource."

172

Estou tentando fazer com que as imagens sejam exibidas em um WPF ListView com o estilo de WrapPanel, conforme descrito neste antigo artigo da equipe do ATC Avalon: Como criar uma exibição personalizada .

Quando tento preencher o ListView com uma coleção de LINQ to Entities consultada de objetos do ADO.NET Entity Framework, recebo a seguinte exceção:

Exceção

A coleção de itens deve estar vazia antes de usar o ItemsSource.

Meu código

Visual básico

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>

Eu coloquei um ponto de interrupção nessa linha. ListViewImages.ItemsSourceé um Nothingpouco antes da atribuição LINQ.

Zack Peterson
fonte

Respostas:

127

A razão pela qual essa exceção específica é lançada é que o conteúdo do elemento é aplicado à coleção de Itens do ListView. Portanto, o XAML inicializa o ListView com um único local: ImageView em sua coleção de itens. Mas, ao usar um ItemsControl, você deve usar a propriedade Items ou a propriedade ItemsSource, não é possível usar os dois ao mesmo tempo. Portanto, quando o atributo ItemsSource é processado, uma exceção é lançada.

Você pode descobrir a qual propriedade o conteúdo de um elemento será aplicado, procurando o ContentPropertyAttribute na classe. Nesse caso, é definido mais alto na hierarquia de classes, no ItemsControl:

[ContentPropertyAttribute("Items")]

A intenção aqui era que a Visualização do ListView fosse definida como um local: ImageView, para que a correção seja indicar explicitamente a propriedade a ser definida.

Corrija o XAML e a exceção desaparecerá:

<ListView Name="ListViewImages"
          SelectionMode="Single"
          ItemsSource="{Binding}">
    <ListView.View>
        <local:ImageView />
    </ListView.View>
</ListView>

Estava faltando essa <ListView.View>etiqueta.

Dave
fonte
6
Esta resposta está correta. Mas antes de verificar esse caso, verifique se o seu xaml está correto, conforme mencionado em outras respostas. Caso contrário, você pode gastar muito tempo olhando para o ItemSource etc, apenas para descobrir que isso é causado por um pequeno erro de digitação.
Pjm
182

Eu tive esse mesmo erro por um tempo em um cenário um pouco diferente. eu tinha

<wpftoolkit:DataGrid
    AutoGenerateColumns="False"
    ItemsSource="{Binding Path=Accounts}" >
    <wpftoolkit:DataGridTextColumn 
        Header="Account Name" 
        Binding="{Binding Path=AccountName}" />
</wpftoolkit:DataGrid>

que eu consertei 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>
Kenwarner
fonte
15
Obrigado! Um problema tão simples ... mas um erro tão confuso.
Scott
15
Para mim, a diferença estava simplesmente faltando o <DataGrid.Columns> (e eu nem estava usando o wpftoolkit).
Dave
1
Faltando o <DataGrid.Columns> para mim também.
Eternal21
67

Acabei de encontrar um exemplo MUITO insidioso deste problema. Meu fragmento original era muito mais complexo, o que dificultava a visualização do erro.

   <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>

O inseto? O extra > após a <ItemsControl>tag de abertura inicial ! Foi <aplicado à coleção de itens interna. Quando o DataContext foi definido posteriormente, falha instantânea. Portanto, procure mais do que apenas erros ao redor dos filhos de dados específicos do ItemsControl ao depurar esse problema.

Armentage
fonte
4
O mesmo aconteceu comigo: Extra >=> Exception
surfen
7
é claro que não é só isso que fará isso. quaisquer caracteres digitados acidentalmente se tornarão itens sozinhos. você pode verificar essa condição excluindo temporariamente o atributo ItemsSource. Se você ainda tiver linhas na grade de dados, precisará verificar se há caracteres estranhos.
Simon_Weaver
4
Armentage ... você acabou de me salvar Eu não sei quantas horas procurando por isso !!! Muito obrigado por postar isso ... votando!
31413 John Fairbanks
1
Muito interessante. Não sei por que isso não é um erro de compilação. Também me pegou!
shawn1874
1
Oh meu, eu tive o mesmo erro: Extra ">". Posso te pagar uma cerveja? Que erro estranho e quão difícil de encontrar sem um erro de compilação! Isso salvou meu dia!
Björn Grossmann
40

Eu também em um cenário 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>

Agora, quando você concluir com a tag Control.ItemTemplate ausente , tudo voltará ao 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>
Junior Mayhé
fonte
1
Por que o WPF deve ser tão óbvio? Definir o DataTemplate para um ListBox causou exceções engraçadas, mas nenhuma delas estava levando à direção certa.
Alois Kraus
Isso foi corrigido para mim ao usar um <ItemsControl>.
RHaguiuda
27

Eu tive esse mesmo erro em um cenário diferente

<ItemsControl ItemsSource="{Binding TableList}">
    <ItemsPanelTemplate>
        <WrapPanel Orientation="Horizontal"/>
    </ItemsPanelTemplate>
</ItemsControl>

A solução foi adicionar a ItemsControl.ItemsPaneltag antes doItemsPanelTemplate

<ItemsControl ItemsSource="{Binding TableList}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
ehudbk
fonte
Foi isso que corrigiu meu problema!
RDV
14

⚠️ Para indicar a resposta de forma diferente ⚠️

X No Xaml, verifique se não há nós pais ausentes ou nós incorretos nas áreas definidas.

Por exemplo

Isso está falhando:

Não há pai apropriado para o nó filho abaixo:ItemsPanelTemplate

<ItemsControl ItemsSource="{Binding TimeSpanChoices}">
    <ItemsPanelTemplate>
        <UniformGrid Rows="1" />
    </ItemsPanelTemplate>
    ...
</ItemsControl>

Isso está funcionando:

<ItemsControl ItemsSource="{Binding TimeSpanChoices}">
    <ItemsControl.ItemsPanel> <!-- I am the missing parent! -->
        <ItemsPanelTemplate>
            <UniformGrid Rows="1" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    ...    
</ItemsControl>

💡 Existe um nó pai adequado do <ItemsControl.ItemsPanel>^^^ fornecido. 💡

ΩmegaMan
fonte
2
Este. Estava ausente <DataGrid.Columns>e tinha colunas de modelo diretamente dentro <DataGrid>. Erro estranho para isso.
Andrew Grothe
12

Exceção

A coleção de itens deve estar vazia antes de usar o ItemsSource.

Essa exceção ocorre quando você adiciona itens às ItemsSource fontes diferentes . Portanto, verifique se você não perdeu uma tag acidentalmente , perdeu uma tag, adicionou tags extras ou escreveu errado uma tag.

<!--Right-->

<ItemsControl ItemsSource="{Binding MyItems}">
     <ItemsControl.ItemsPanel.../>
     <ItemsControl.MyAttachedProperty.../>
     <FrameworkElement.ActualWidth.../>
</ItemsControl>


<!--WRONG-->

<ItemsControl ItemsSource="{Binding MyItems}">
     <Grid.../>
     <Button.../>
     <DataTemplate.../>
     <Heigth.../>
</ItemsControl>

Enquanto ItemsControl.ItemsSourcejá estiver definido Binding, outros itens (Grade, Botão, ...) não podem ser adicionados à fonte. No entanto, enquanto nãoItemsSource estiver em uso, o seguinte código é permitido :

<!--Right-->
<ItemsControl>
     <Button.../>
     <TextBlock.../>
     <sys:String.../>
</ItemsControl>

observe a ItemsSource="{Binding MyItems}"parte que falta .

Bizhan
fonte
2
Algo no que você disse aqui me levou a dar uma boa olhada nas minhas colunas da grade de dados ... então percebi que elas não estavam em uma tag datagrid.columns. +1 por me dar uma corrida mental.
Craig Brett
4

No meu caso, era apenas um StackPanel extra dentro do 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>

Torna-se:

<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>

e está tudo bem.

Carl
fonte
4

No meu caso, ele não estava usando um DataTemplate para o ItemsControl.

Velho:

<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>

Novo:

<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>
samiz
fonte
I deve agradecer-lhe 4 horas, o tempo que passei tentando consertar essa bagunça ... OBRIGADO
Mark
4

O meu estava com um estilo datagrid. Se você deixar de fora as <DataGrid.RowStyle>tags em torno do estilo, terá esse problema. O estranho é que funcionou por um tempo assim. Aqui está o código incorreto.

 <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>

e o bom

 <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>
PatFromCanada
fonte
3

Eu tive o mesmo erro. O problema foi esse símbolo extra ">" adicionado por engano entre as tags </ComboBox.SelectedValue> e </ComboBox>:

<ComboBox 
   ItemsSource="{Binding StatusTypes}"
   DisplayMemberPath="StatusName"
   SelectedValuePath="StatusID">
   <ComboBox.SelectedValue>
      <Binding Path="StatusID"/>
   </ComboBox.SelectedValue>
   >
</ComboBox>

e aqui está o código correto:

<ComboBox 
   ItemsSource="{Binding StatusTypes}"
   DisplayMemberPath="StatusName"
   SelectedValuePath="StatusID">
   <ComboBox.SelectedValue>
      <Binding Path="StatusID"/>
   </ComboBox.SelectedValue>
</ComboBox>
Vladimir Trifonov
fonte
2

Eu tive esse erro quando tentei aplicar menus de contexto ao meu TreeView. Essas tentativas acabaram em um XAML ruim, que foi compilado de alguma forma:

<TreeView Height="Auto" MinHeight="100"  ItemsSource="{Binding Path=TreeNodes, Mode=TwoWay}" 
    ContextMenu="{Binding Converter={StaticResource ContextMenuConverter}}">
    ContextMenu="">
    <TreeView.ItemContainerStyle>
    ...  

Observe a linha problemática: ContextMenu="">.
Não sei por que ele foi compilado, mas achei que vale a pena mencionar como uma razão para essa mensagem de exceção enigmática. Como Armentage disse, olhe ao redor do XAML com cuidado, especialmente nos lugares que você editou recentemente.

Noich
fonte
2

Encontrei esse erro em outra situação. Tentei definir um estilo para TreeViewItems diretamente dentro do <TreeView>, mas em vez disso deveria incorporá-lo <TreeView.ItemContainerStyle>.

Errado:

<TreeView ItemsSource="{Binding ExampleListView}">
    <Style TargetType="{x:Type TreeViewItem}">
        <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
    </Style>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding SubItemListList}">
        ...
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

Corrigir:

<TreeView ItemsSource="{Binding ExampleListView}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
        </Style>
    </TreeView.ItemContainerStyle>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding SubItemListList}">
        ...
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>
RonnyR
fonte
1

Talvez não seja uma resposta tão útil, mas tive o mesmo problema ao alterar a ordem das colunas e cometi erros como o da amostra a seguir. Tendo muitas colunas, reordenei-as e colei de alguma maneira uma após fechar a tag /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>

Enfim, perdeu meia hora por causa disso. Espero que isso ajude os outros.

Andrei Floroiu
fonte
1

Corri para esse problema porque um nível de tag, <ListView.View>para ser específico, estava ausente no meu XAML.

Este código produziu esse erro.

<Grid>
    <ListView Margin="10" Name="lvDataBinding" >
        <GridView>
            <GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
            <GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
            <GridViewColumn Header="Mail" Width="150" DisplayMemberBinding="{Binding Mail}" />
        </GridView>
    </ListView>
</Grid>

O seguinte corrigiu

<Grid>
    <ListView Margin="10" Name="lvDataBinding" >
        <ListView.View> <!-- This was missing in top! -->
            <GridView>
                <GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
                <GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
                <GridViewColumn Header="Mail" Width="150" DisplayMemberBinding="{Binding Mail}" />
            </GridView>
        </ListView.View>
    </ListView>
</Grid>
zar
fonte
-1

Cuidado com erros de digitação! Eu tive o seguinte

<TreeView ItemsSource="{Binding MyCollection}">
    <TreeView.Resources>
        ...
    </TreeView.Resouces>>
</TreeView>

(Observe o tailing > , que é interpretado como conteúdo, então você está definindo o dobro do conteúdo ... Demorou um pouco :)

ElGauchooo
fonte
Armentage já mencionou isso, com um pouco mais de explicação.
Ben Voigt