"Die Elementsammlung muss leer sein, bevor ItemsSource verwendet werden kann."

172

Ich versuche, Bilder in einer WPF-Listenansicht anzuzeigen, die wie ein WrapPanel gestaltet ist, wie in diesem alten Artikel des ATC Avalon-Teams beschrieben: So erstellen Sie eine benutzerdefinierte Ansicht .

Wenn ich versuche, die ListView mit einer von LINQ-to-Entities abgefragten Sammlung von ADO.NET Entity Framework-Objekten zu füllen, wird die folgende Ausnahme angezeigt:

Ausnahme

Die Elementsammlung muss leer sein, bevor ItemsSource verwendet werden kann.

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

Ich habe einen Haltepunkt in diese Zeile gesetzt. ListViewImages.ItemsSourceist Nothingkurz vor der LINQ-Zuweisung.

Zack Peterson
quelle

Antworten:

127

Der Grund, warum diese spezielle Ausnahme ausgelöst wird, ist, dass der Inhalt des Elements auf die Items-Auflistung von ListView angewendet wird. Daher initialisiert die XAML die ListView mit einem einzigen lokalen: ImageView in ihrer Items-Auflistung. Wenn Sie jedoch ein ItemsControl verwenden, müssen Sie entweder die Items-Eigenschaft oder die ItemsSource-Eigenschaft verwenden. Sie können nicht beide gleichzeitig verwenden. Wenn das ItemsSource-Attribut verarbeitet wird, wird daher eine Ausnahme ausgelöst.

Sie können herausfinden, auf welche Eigenschaft der Inhalt eines Elements angewendet wird, indem Sie in der Klasse nach dem ContentPropertyAttribute suchen. In diesem Fall ist es in der Klassenhierarchie im ItemsControl höher definiert :

[ContentPropertyAttribute("Items")]

Die Absicht hier war, dass die Ansicht der ListView auf eine lokale: ImageView festgelegt wird, sodass der Fix darin besteht, die festzulegende Eigenschaft explizit anzugeben.

Korrigieren Sie die XAML und die Ausnahme verschwindet:

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

Es fehlte dieses <ListView.View>Tag.

Dave
quelle
6
Diese Antwort ist richtig. Bevor Sie jedoch nach diesem Fall suchen, überprüfen Sie, ob Ihre xaml korrekt ist, wie in anderen Antworten erwähnt. Andernfalls können Sie viel Zeit damit verbringen, sich ItemSources usw. anzusehen, um schließlich festzustellen, dass dies durch einen kleinen Tippfehler verursacht wird.
pjm
182

Ich hatte den gleichen Fehler für eine Weile in einem etwas anderen Szenario. ich hatte

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

was ich festlegte zu sein

<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
quelle
15
Danke dir! So ein einfaches Problem ... aber so ein verwirrender Fehler.
Scott
15
Für mich fehlte der Unterschied einfach die <DataGrid.Columns> (und ich habe nicht einmal das wpftoolkit verwendet).
Dave
1
Ich vermisse auch die <DataGrid.Columns> für mich.
Eternal21
67

Ich bin gerade auf ein SEHR heimtückisches Beispiel für dieses Problem gestoßen. Mein ursprüngliches Fragment war viel komplexer, was es schwierig machte, den Fehler zu erkennen.

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

Der Fehler? Das Extra > nach dem ersten Eröffnungs- <ItemsControl>Tag! Das <wurde auf die eingebaute Items-Sammlung angewendet. Wenn der DataContext später festgelegt wurde, sofortige Crashola. Achten Sie beim Debuggen dieses Problems auf mehr als nur Fehler in Ihren ItemsControl-spezifischen untergeordneten Daten.

Armentage
quelle
4
Das gleiche passierte mir: Extra >=> Ausnahme
surfen
7
Natürlich wird dies nicht nur getan. Alle versehentlich eingegebenen Zeichen werden von selbst zu Elementen. Sie können diese Bedingung überprüfen, indem Sie Ihr ItemsSource-Attribut vorübergehend löschen. Wenn Sie noch Zeilen im
Datenraster haben,
4
Armentage ... du hast mich gerade gerettet Ich weiß nicht, wie viele Stunden ich danach gesucht habe !!! Vielen Dank für die Veröffentlichung ... Abstimmung!
John Fairbanks
1
Sehr interessant. Ich bin mir nicht sicher, warum das kein Kompilierungsfehler ist. Es hat mich auch!
shawn1874
1
Oh mein Gott, ich hatte den gleichen Fehler: Extra ">". Kann ich dir ein Bier kaufen? Was für ein seltsamer Fehler und wie schwer zu finden ohne einen Kompilierungsfehler! Das hat mir den Tag gerettet!
Björn Grossmann
40

Ich auch in einem anderen Szenario.

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

Wenn Sie nun das fehlende Tag Control.ItemTemplate vervollständigen , wird alles 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é
quelle
1
Warum muss WPF so verdammt unauffällig sein? Das Festlegen der DataTemplate für eine ListBox verursachte lustige Ausnahmen, aber keine davon führte in die richtige Richtung.
Alois Kraus
Dies wurde bei der Verwendung von a behoben <ItemsControl>.
RHaguiuda
27

Ich hatte den gleichen Fehler in einem anderen Szenario

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

Die Lösung bestand darin, das ItemsControl.ItemsPanelTag vor dem hinzuzufügenItemsPanelTemplate

<ItemsControl ItemsSource="{Binding TableList}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
ehudbk
quelle
Dies hat mein Problem behoben!
RDV
14

⚠️ Um die Antwort anders anzugeben ⚠️

💡 Stellen Sie in Xaml sicher , dass in den definierten Bereichen keine fehlenden übergeordneten Knoten oder falschen Knoten vorhanden sind.

Beispielsweise

Dies schlägt fehl:

Für den untergeordneten Knoten gibt es kein geeignetes übergeordnetesItemsPanelTemplate Element:

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

Das funktioniert:

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

💡 Es gibt einen richtigen übergeordneten Knoten von <ItemsControl.ItemsPanel>bereitgestellt ^^^. 💡

ΩmegaMan
quelle
2
Dies. Fehlt <DataGrid.Columns>und hatte Vorlagenspalten direkt im Inneren <DataGrid>. Seltsamer Fehler dafür.
Andrew Grothe
12

Ausnahme

Die Elementsammlung muss leer sein, bevor ItemsSource verwendet werden kann.

Diese Ausnahme tritt auf, wenn Sie Elemente ItemsSource über verschiedene Quellen hinzufügen . Stellen Sie also sicher, dass Sie nicht versehentlich ein Tag verpasst, ein Tag falsch platziert, zusätzliche Tags hinzugefügt oder ein Tag falsch geschrieben haben.

<!--Right-->

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


<!--WRONG-->

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

Während ItemsControl.ItemsSourcebereits festgelegt Binding, können andere Elemente (Raster, Schaltfläche, ...) nicht zur Quelle hinzugefügt werden. Doch während ItemsSourcesich nicht in Benutzung der folgende Code erlaubt :

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

Beachten Sie das fehlende ItemsSource="{Binding MyItems}"Teil.

Bizhan
quelle
2
Etwas in dem, was Sie hier gesagt haben, hat mich dazu veranlasst, mir meine Datenrasterspalten genauer anzusehen ... dann wurde mir klar, dass sie sich nicht in einem datagrid.columns-Tag befanden. +1 für das mentale Joggen.
Craig Brett
4

In meinem Fall war es nur ein zusätzliches StackPanel in der 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>

Wird:

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

und alles ist gut.

Carl
quelle
4

In meinem Fall wurde keine DataTemplate für das ItemsControl verwendet.

Alt:

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

Neu:

<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
quelle
Ich sollte Sie 4 Stunden danken, die Zeit , die ich damit verbracht haben versucht , dieses Chaos zu beheben ... DANKE
Mark
4

Meins war mit einem Datagrid-Stil. Wenn Sie die <DataGrid.RowStyle>Tags um den Stil weglassen, tritt dieses Problem auf. Seltsam ist, dass es eine Weile so funktioniert hat. Hier ist der schlechte 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>

und das gute

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

Ich hatte den gleichen Fehler. Das Problem war, dass dieses zusätzliche Symbol ">" versehentlich zwischen den Tags </ComboBox.SelectedValue> und </ ComboBox> hinzugefügt wurde:

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

und hier ist der richtige Code:

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

Ich hatte diesen Fehler, als ich versuchte, Kontextmenüs auf meine anzuwenden TreeView. Diese Versuche endeten in einer schlechten XAML, die sich irgendwie zusammensetzte:

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

Beachten Sie die problematische Zeile : ContextMenu="">.
Ich weiß nicht, warum es kompiliert wurde, aber ich dachte, es ist erwähnenswert als Grund für diese kryptische Ausnahmemeldung. Schauen Sie sich, wie Armentage sagte, die XAML genau an, insbesondere an Stellen, die Sie kürzlich bearbeitet haben.

Noich
quelle
2

Ich bin auf diesen Fehler in einer anderen Situation gestoßen. Ich habe versucht, einen Stil für TreeViewItems direkt in der zu definieren <TreeView>, sollte diesen aber stattdessen eingebettet haben <TreeView.ItemContainerStyle>.

Falsch:

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

Richtig:

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

Vielleicht keine so nützliche Antwort, aber ich hatte das gleiche Problem beim Ändern der Spaltenreihenfolge und habe einen Fehler wie im folgenden Beispiel gemacht. Da ich viele Spalten hatte, ordnete ich sie neu und fügte nach dem Schließen des Tags eine ein /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>

Jedenfalls eine halbe Stunde dadurch verloren. Hoffe das hilft anderen.

Andrei Floroiu
quelle
1

Ich bin auf dieses Problem <ListView.View>gestoßen, weil in meiner XAML eine Tag-Ebene fehlte , um genau zu sein.

Dieser Code hat diesen Fehler erzeugt.

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

Das Folgende hat es behoben

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

Vorsicht vor Tippfehlern! Ich hatte folgendes

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

(Beachten Sie das Tailing > , das als Inhalt interpretiert wird, sodass Sie den doppelten Inhalt festlegen ... Hat eine Weile gedauert :)

ElGauchooo
quelle
Armentage hat dies bereits erwähnt, mit etwas mehr Erklärung.
Ben Voigt