«Коллекция предметов должна быть пустой перед использованием ItemsSource».

172

Я пытаюсь получить изображения для отображения в WPF ListView, стилизованном под WrapPanel, как описано в этой старой статье команды ATC Avalon: как создать пользовательское представление .

Когда я пытаюсь заполнить ListView набором объектов запросов ADO.NET Entity Framework, запрашиваемым LINQ-to-Entities, я получаю следующее исключение:

исключение

Коллекция предметов должна быть пустой перед использованием ItemsSource.

Мой код ...

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>

Я поставил точку останова на этой линии. ListViewImages.ItemsSourceкак Nothingраз перед назначением LINQ.

Зак Петерсон
источник

Ответы:

127

Причина, по которой выбрасывается это конкретное исключение, заключается в том, что содержимое элемента применяется к коллекции элементов ListView. Таким образом, XAML инициализирует ListView одним локальным: ImageView в своей коллекции Items. Но при использовании ItemsControl вы должны использовать либо свойство Items, либо свойство ItemsSource, вы не можете использовать оба одновременно. Следовательно, когда обрабатывается атрибут ItemsSource, генерируется исключение.

Вы можете узнать, к какому свойству будет применено содержимое элемента, найдя ContentPropertyAttribute в классе. В этом случае он определен выше в иерархии классов, на ItemsControl:

[ContentPropertyAttribute("Items")]

Намерение здесь состояло в том, чтобы ViewView List был установлен локально: ImageView, так что исправление должно явно указывать свойство, которое будет установлено.

Исправьте XAML, и исключение исчезнет:

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

Отсутствовал этот <ListView.View>тег.

Дейв
источник
6
Этот ответ правильный. Но прежде чем проверять этот случай, убедитесь, что ваш xaml правильный, как указано в других ответах. В противном случае вы можете потратить много времени на просмотр ItemSource и т. Д., Но в конечном итоге обнаружите, что это вызвано небольшой опечаткой.
PJM
182

У меня была такая же ошибка некоторое время в немного другом сценарии. я имел

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

который я исправил

<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
источник
15
Спасибо! Такая простая проблема ... но такая запутанная ошибка.
Скотт
15
Для меня разница в том, что мне просто не хватает <DataGrid.Columns> (а я даже не использовал wpftoolkit).
Дейв
1
Отсутствует <DataGrid.Columns> для меня, а также.
Eternal21
67

Я просто наткнулся на ОЧЕНЬ коварный пример этой проблемы. Мой оригинальный фрагмент был намного более сложным, что затрудняло увидеть ошибку.

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

Ошибка? Дополнительный > после начального открытия <ItemsControl>тега! <GOT применяется к встроенным в пунктах сбора. Когда позже был задан DataContext, мгновенный крах. Поэтому при отладке этой проблемы обращайте внимание не только на ошибки, которые окружают ваши дочерние элементы данных ItemsControl.

Armentage
источник
4
То же самое случилось со мной: Extra >=> Exception
surfen
7
Конечно, это не только>, что сделает это. любые случайно набранные персонажи сами становятся предметами. Вы можете проверить это условие, временно удалив свой атрибут ItemsSource. Если у вас все еще есть строки в сетке данных, вам нужно проверить наличие посторонних символов
Simon_Weaver
4
Арментаж ... ты только что спас меня, я не знаю, сколько часов искал это !!! Большое спасибо за публикацию этого ... голосование вверх!
Джон Фэрбенкс
1
Очень интересно. Я не уверен, почему это не ошибка компиляции. Это меня тоже достало!
shawn1874
1
Боже мой, у меня была та же ошибка: дополнительные ">". Могу я купить тебе пиво? Какая странная ошибка и как трудно найти без ошибки компиляции! Это спасло мой день!
Бьорн Гроссманн
40

Я тоже по другому сценарию.

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

Теперь, когда вы закончите с отсутствующим тегом Control.ItemTemplate , все нормализуется:

<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>
Джуниор Майе
источник
1
Почему WPF так чертовски неочевиден? Установка DataTemplate для ListBox вызвала забавные исключения, но ни одно из них не привело к правильному направлению.
Алоис Краус
Это исправлено для меня при использовании <ItemsControl>.
RHaguiuda
27

У меня была такая же ошибка в другом сценарии

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

Решением было добавить ItemsControl.ItemsPanelтег передItemsPanelTemplate

<ItemsControl ItemsSource="{Binding TableList}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
ehudbk
источник
Это то, что исправило мою проблему!
RDV
14

⚠️ Чтобы сформулировать ответ по-другому ⚠️

💡 В Xaml убедитесь, что в указанных областях отсутствуют отсутствующие родительские узлы или неправильные узлы .

Например

Это терпит неудачу:

Ниже нет подходящего родителя для ItemsPanelTemplateдочернего узла:

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

Это работает:

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

Parent Существует правильный родительский узел из <ItemsControl.ItemsPanel>предоставленного ^^^. 💡

ΩmegaMan
источник
2
Это. Отсутствовал <DataGrid.Columns>и имел столбцы шаблона прямо внутри <DataGrid>. Странная ошибка для этого.
Эндрю Грот
12

исключение

Коллекция предметов должна быть пустой перед использованием ItemsSource.

Это исключение возникает при добавлении элементов в ItemsSource различные источники . Поэтому убедитесь, что вы случайно не пропустили тег, не поместили тег, не добавили дополнительные теги или не написали тег.

<!--Right-->

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


<!--WRONG-->

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

Пока ItemsControl.ItemsSourceэто уже установлено Binding, другие элементы (Сетка, Кнопка, ...) не могут быть добавлены к источнику. Однако в то время ItemsSourceкак не в использовании следующий код разрешается :

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

обратите внимание на недостающую ItemsSource="{Binding MyItems}"часть.

Бижан
источник
2
Что-то в том, что вы сказали здесь, побудило меня внимательно взглянуть на столбцы моей сетки данных ... потом я понял, что их нет в теге datagrid.columns. +1 за то, что дал мне умственную пробежку.
Крейг Бретт
4

В моем случае это была просто дополнительная StackPanel внутри 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>

становится:

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

и все хорошо.

деревенщина
источник
4

В моем случае он не использовал DataTemplate для ItemsControl.

Старый:

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

Новое:

<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
источник
Я должен поблагодарить вас 4 часа, время, которое я потратил, пытаясь исправить этот беспорядок ... СПАСИБО
Марк
4

Мой был с стилем данных. Если вы пропустите <DataGrid.RowStyle>теги вокруг стиля, вы получите эту проблему. Странно то, что какое-то время это работало. Вот плохой код.

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

и хорошо

 <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
источник
3

У меня была такая же ошибка. Проблема заключалась в том, что этот дополнительный символ «>» был добавлен по ошибке между тегами </ComboBox.SelectedValue> и </ ComboBox>:

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

и вот правильный код:

<ComboBox 
   ItemsSource="{Binding StatusTypes}"
   DisplayMemberPath="StatusName"
   SelectedValuePath="StatusID">
   <ComboBox.SelectedValue>
      <Binding Path="StatusID"/>
   </ComboBox.SelectedValue>
</ComboBox>
Владимир Трифонов
источник
2

У меня была эта ошибка, когда я пытался применить контекстное меню к моему TreeView. Эти попытки закончились неудачным XAML, который каким-то образом компилировался:

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

Обратите внимание на проблемную строку: ContextMenu="">.
Я не знаю, почему это скомпилировано, но я решил, что стоит упомянуть в качестве причины этого загадочного сообщения об исключении. Как сказал Арментаж, внимательно осмотрите XAML, особенно в местах, которые вы недавно редактировали.

Noich
источник
2

Я столкнулся с этой ошибкой в ​​другой ситуации. Я попытался определить стиль для TreeViewItems непосредственно в <TreeView>, но вместо этого должен был встроить его в <TreeView.ItemContainerStyle>.

Неправильно:

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

Верный:

<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
источник
1

Возможно, не очень полезный ответ, но у меня была та же проблема при изменении порядка столбцов, и я допустил ошибку, подобную приведенной в следующем примере. Имея много столбцов, я переупорядочил их и как-то вставил один после закрытия тега /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>

Во всяком случае, потерял полчаса из-за этого. Надеюсь, что это помогает другим.

Андрей Флоройу
источник
1

Я столкнулся с этой проблемой, потому что один уровень тега, <ListView.View>если быть точным, отсутствовал в моем XAML.

Этот код выдал эту ошибку.

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

Следующее исправило это

<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>
зар
источник
-1

Остерегайтесь опечаток! У меня было следующее

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

(Обратите внимание на хвост > , который интерпретируется как контент, так что вы устанавливаете контент в два раза ... У меня ушло немного времени :)

ElGauchooo
источник
Арментаж уже упоминал об этом, с немного большим объяснением.
Бен Фойгт