196

I'm trying to get images to display in a WPF ListView styled like a WrapPanel as described in this old ATC Avalon Team article: How to Create a Custom View.

When I try to populate the ListView with a LINQ-to-Entities queried collection of ADO.NET Entity Framework objects I get the following exception:

Exception

Items collection must be empty before using ItemsSource.

My code…

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>

I put a breakpoint on that line. ListViewImages.ItemsSource is Nothing just before the LINQ assignment.

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Zack Peterson
  • 56,055
  • 78
  • 209
  • 280

19 Answers19

213

I had this same error for a while in a slightly different scenario. The cause was invalid XAML, because some tags were missing.

I had

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

which I fixed to be

<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>
StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
kenwarner
  • 28,650
  • 28
  • 130
  • 173
132

The reason this particular exception gets thrown is that the content of the element gets applied to the ListView's Items collection. So the XAML initialises the ListView with a single local:ImageView in its Items collection. But when using an ItemsControl you must use either the Items property or the ItemsSource property, you can't use both at the same time. Hence when the ItemsSource attribute gets processed an exception is thrown.

You can find out which property the content of an element will get applied to by looking for the ContentPropertyAttribute on the class. In this case it's defined higher in the class hierarchy, on the ItemsControl:

[ContentPropertyAttribute("Items")]

The intention here was that the ListView's View be set to a local:ImageView so the fix is to explicitly indicate the property to be set.

Fix the XAML and the exception goes away:

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

It was missing that <ListView.View> tag.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Dave
  • 4,420
  • 1
  • 34
  • 39
  • 6
    This answer is correct. But before checking for this case do check that your xaml is correct as mentioned in other answers. Otherwise you can spend a lot of time looking at ItemSource's etc only to eventually find that its caused by a small typo. – pjm Nov 21 '16 at 12:31
76

I just ran into a VERY insidious example of this problem. My original fragment was much more complex, which made it difficult to see the 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>

The bug? The extra > after the initial opening <ItemsControl> tag! The < got applied to the built-in Items collection. When the DataContext was later set, instant crashola. So look out for more than just errors surround your ItemsControl specific data children when debugging this problem.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
Armentage
  • 12,065
  • 8
  • 33
  • 33
  • 4
    The same happened to me: Extra `>` => Exception – surfen Dec 11 '11 at 01:51
  • 8
    of course it's not just > that will do this. any accidentally typed characters will become items by themselves. you can check for this condition by temporarily deleting your ItemsSource attribute. If you still have rows in the data grid then you need to check for extraneous characters – Simon_Weaver Jul 17 '12 at 03:10
  • 5
    Armentage... you just saved me I don't know how many hours of looking for this!!! Thanks so much for posting this... voting up! – John Fairbanks Aug 03 '14 at 22:23
  • 1
    Very interesting. I'm not sure why that is not a compile error. It got me too! – shawn1874 Mar 19 '15 at 16:02
  • In my case, the problem was in code behind (this is an old project where the author didn't understand binding very well), but your example pointed me in the right direction. What was happening is that when the source collection had no elements, they were deleting the binding then manually adding an item to the items collection that said "none". Then later if elements were added to the source collection, they weren't bothering to clear out the manually created element before trying to re-add the binding. Your "stray element" example rang the right bell to get me thinking! Thanks! – Steve In CO Jul 08 '15 at 20:20
  • 2
    Oh my, I had the same error: Extra ">". Can I buy you a beer? What a strange error and how difficult to find without a compile error! This saved my day! – Björn Grossmann Aug 07 '15 at 08:32
  • The same happened to me but with an extra "-" after – Rowandish May 03 '16 at 10:50
  • I had forgotten all together. – Anthony Nichols Jul 14 '16 at 15:17
  • 1
    Had this as well, but then with `//`. Accidentally commented out xaml with C# comment style. – Denxorz May 15 '19 at 12:53
42

Me too on a different scenario.

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

Now when you complete with the missing tag Control.ItemTemplate, everything gets to 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é
  • 16,144
  • 26
  • 115
  • 161
27

I had this same error in a different scenario

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

The solution was to add the ItemsControl.ItemsPanel tag before the ItemsPanelTemplate

<ItemsControl ItemsSource="{Binding TableList}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
ehudbk
  • 279
  • 3
  • 2
17

⚠️ To state the answer differently ⚠️

In Xaml verify that there are no Missing Parent Nodes or incorrect nodes in the defined areas.

For example

This Is Failing:

There is no proper parent for the ItemsPanelTemplate child node below:

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

This Is Working:

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

There is the proper parent node of <ItemsControl.ItemsPanel> provided^^^.

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
14

Exception

Items collection must be empty before using ItemsSource.

This exception occurs when you add items to the ItemsSource through different sources. So Make sure you haven't accidentally missed a tag, misplaced a tag, added extra tags, or miswrote a tag.

<!--Right-->

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


<!--WRONG-->

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

While ItemsControl.ItemsSource is already set through Binding, other items (Grid, Button, ...) can't be added to the source. However while ItemsSource is not in-use the following code is allowed:

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

notice the missing ItemsSource="{Binding MyItems}" part.

Bizhan
  • 16,157
  • 9
  • 63
  • 101
  • 3
    Something in what you said here prompted me to take a long hard look at my data grid columns... then I realized they weren't in a datagrid.columns tag. +1 for giving me the mental jog. – Craig Brett Apr 02 '17 at 00:00
6

Keep template column inside DataGrid.Columns. This helped me resolve this issue.

Ref: DataGridTemplateColumn : Items collection must be empty before using ItemsSource.

Community
  • 1
  • 1
Ram
  • 15,908
  • 4
  • 48
  • 41
5

In my case, it was not using a DataTemplate for the ItemsControl.

Old:

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

New:

<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
  • 1,043
  • 1
  • 13
  • 21
  • I should thank you 4 hours, the time I have spent trying to fix this mess ... THANK YOU – Mark Apr 17 '18 at 18:10
4

Mine was with a datagrid Style. If you leave out the <DataGrid.RowStyle> tags around the Style you get that problem. Weird thing is it worked for a while like that. Here is the bad code.

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

and the good

 <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
  • 2,738
  • 1
  • 27
  • 27
4

I had the same error. The problem was this extra symbol ">" added by mistake between the tags </ComboBox.SelectedValue> and </ComboBox>:

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

and here is the correct code:

<ComboBox 
   ItemsSource="{Binding StatusTypes}"
   DisplayMemberPath="StatusName"
   SelectedValuePath="StatusID">
   <ComboBox.SelectedValue>
      <Binding Path="StatusID"/>
   </ComboBox.SelectedValue>
</ComboBox>
Vladimir Trifonov
  • 1,395
  • 11
  • 9
4

In My case, it was just an extra StackPanel inside the 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>

Becomes:

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

and all is well.

Carl
  • 41
  • 1
3

There are many possible reasons for getting this error. In my case, I was adding a datagrid column outside the 'columns' tag. like displayed in image. Surpisingly there was no error given by XAML editor. misplaced xaml

Himanshu Mange
  • 104
  • 1
  • 10
2

I encountered this error in another situation. I tried to defined a style for TreeViewItems directly within the <TreeView>, but instead should have embedded that within <TreeView.ItemContainerStyle>.

Wrong:

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

Correct:

<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
  • 210
  • 1
  • 5
2

I ran into this problem because one level of tag, <ListView.View> to be specirfic, was missing in my XAML.

This code produced this error.

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

The following fixed it

<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
  • 11,361
  • 14
  • 96
  • 178
2

I've had this error when I tried applying context menus to my TreeView. Those tries ended up in a bad XAML which compiled somehow:

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

Note the problematic line: ContextMenu=""> .
I don't know why it compiled, but I figured it's worth mentioning as a reason for this cryptic exception message. Like Armentage said, look around the XAML carefully, especially in places you've recently edited.

Noich
  • 14,631
  • 15
  • 62
  • 90
1

Perhaps not such an useful answer, but I had the same problem when changing column order and made mistake like the one in the following sample. Having a lot of columns, I reordered them and somehow pasted one after closing 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>

Anyway, lost half an hour because of this. Hope this helps others.

0

Beware of typos! I had the following

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

(Notice the tailing >, which is interpreted as content, so you're setting twice the content... Took me a while :)

ElGauchooo
  • 4,256
  • 2
  • 13
  • 16
0

I had the very same error.
In my case, i just removed a single line <UniformGrid Columns="3" />

<ListBox>
    <UniformGrid Columns="3" /> // remove this line!!!!
    ...
</ListBox>
Pixel_95
  • 954
  • 2
  • 9
  • 21