"Колекція елементів повинна бути порожньою, перш ніж використовувати ItemSource."


172

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

Коли я намагаюся заповнити ListView списком запитів LINQ до сущностей об'єктів ADO.NET Entity Framework, я отримую таке виняток:

Виняток

Колекція елементів повинна бути порожньою, перш ніж використовувати 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 у своїй колекції елементів. Але при використанні ItemControl ви повинні використовувати або властивість Items, або властивість ItemsSource, ви не можете використовувати обидва одночасно. Отже, коли обробляється атрибут ItemsSource, викидається виняток.

Ви можете дізнатися, до якого властивості буде застосовано вміст елемента, шукаючи ContentPropertyAttribute на класі. У цьому випадку це визначено вище в ієрархії класів, на ItemsControl:

[ContentPropertyAttribute("Items")]

Тут наміром було, щоб перегляд ListView було встановлено на локальний: ImageView, щоб виправлення явно вказувало властивість, яку потрібно встановити.

Виправте XAML, і виняток піде:

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

Цього <ListView.View>тегу не було.


6
Ця відповідь правильна. Але перед тим, як перевірити цей випадок, переконайтеся, що ваш xaml правильний, як зазначено в інших відповідях. В іншому випадку ви можете витратити багато часу, переглядаючи ItemSource і т. Д. Лише, щоб врешті-решт виявити, що це спричинено невеликою помилкою.
пім

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>

15
Дякую! Така проста проблема ... але така заплутана помилка.
Скотт

15
Для мене різниця просто не вистачала <DataGrid.Columns> (і я навіть не використовував wpftoolkit).
Дейв

1
Відсутній і для мене <DataGrid.Columns>.
Вічний21

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, миттєвий збій. Тому слідкуйте за тим, щоб більше, ніж просто помилки, що оточують ваші діти, що відповідають конкретним параметрам ItemControl, під час налагодження цієї проблеми.


4
Те саме трапилось і зі мною: Extra >=> Виняток
surfen

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

Це те, що вирішило мою проблему!
RDV

14

Differently Складати відповідь інакше ⚠️

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

💡 Є належний батьківський вузол <ItemsControl.ItemsPanel>наданого ^^^. 💡


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, інші елементи (Grid, Button, ...) не можуть бути додані до джерела. Однак, поки ItemsSourceвін не використовується , дозволений наступний код :

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

помітити відсутність ItemsSource="{Binding MyItems}"частини.


2
Щось із того, що ви сказали тут, спонукало мене довго пильно дивитися на мої стовпці сітки даних ... тоді я зрозумів, що вони не містяться в тезі datagrid.column. +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 для ControlControl.

Старий:

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

Я повинен подякувати вам 4 години, час, який я витратив, намагаючись виправити цей безлад ... ДЯКУЮ ВАС
Марк

4

Шахта була із DataGrid Style. Якщо ви залишите <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>

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, особливо там, де ви нещодавно редагували.


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>

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>

(Помітьте хвостик > , який інтерпретується як вміст, тому ви встановлюєте вміст удвічі ... Зайняв час :)


Арментаж уже згадував про це, з трохи більшим поясненням.
Бен Войгт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.