2012-06-18 3 views
16

Sono nuovo nella rilegatura e di WPF di recente ho imparato come creare un listBox con più colonne utilizzando tecnologia di rilegaturaL'operazione non è valida mentre ItemsSource è in uso. Accedere e modificare gli elementi con ItemsControl.ItemsSource invece

<ListView ItemsSource="{Binding Items}" Margin="306,70,22,17" MouseDoubleClick="listBoxSS_MouseDoubleClick" Name="listBoxSS" >   
    <ListView.View> 
      <GridView> 
       <GridView.Columns> 
        <GridViewColumn Header="first_name " Width="100" DisplayMemberBinding="{Binding Path=First_name}" /> 
        <GridViewColumn Header="last_name" Width="100" DisplayMemberBinding="{Binding Path=Last_name}" /> 
        <GridViewColumn Header="phone_number" Width="100" DisplayMemberBinding="{Binding Path=Phones[0]}" /> 
        <GridViewColumn Header="notes" Width="100" DisplayMemberBinding="{Binding Path=Notes}" /> 
       </GridView.Columns> 
      </GridView> 
     </ListView.View> 
    </ListView> 

e questo è il codice:

List<Student> arr = search.students(); 
     listBoxSS.ItemsSource = arr; 

ma il problema è stato quando ho provato ad usare aggiungere o rimuovere elemento o chiara

listBoxSS.Items.Clear(); 

prega I ho bisogno di un esempio per usare la fonte degli articoli o il modo in cui posso AGGIUNGERE o rimuovere oggetti o cancellare l'elenco.

EDIT:

<ListView ItemsSource="{Binding Items}" Margin="306,70,22,17" MouseDoubleClick="listBoxSS_MouseDoubleClick" Name="listBoxSS" > 
    <ListView.View> 
     <GridView> 
      <GridView.Columns> 
       <GridViewColumn Header="first_name " Width="100" DisplayMemberBinding="{Binding Path=First_name}" /> 
       <GridViewColumn Header="last_name" Width="100" DisplayMemberBinding="{Binding Path=Last_name}" /> 
       <GridViewColumn Header="phone_number" Width="100" DisplayMemberBinding="{Binding Path=Phones[0]}" /> 
       <GridViewColumn Header="notes" Width="100" DisplayMemberBinding="{Binding Path=Notes}" /> 
      </GridView.Columns> 
     </GridView> 
    </ListView.View> 
</ListView> 

e qui è il codice:

ObservableCollection<Employee> Gemployees; 
var employees = new ObservableCollection<Employee>(search.employees()); 

search.employees() ottenere l'elenco di tutti i dipendenti nel mio DB

listBoxPE.ItemsSource = employees; 
     Gemployees = employees; 

ora posso eseguire tutti i metodi su Gemployees

Gemployees.Remove((Student)listBoxSS.SelectedItem); 
Gemployees.Add((Student)listBoxSS.SelectedItem); 

Il ListView esegue un aggiornamento ogni volta che aggiungo o rimuovo un elemento da Gemployees !! Cool, ma ancora un po 'di duro lavoro sul binding. Ora sto facendo una classe di interfaccia per ogni ListView in modo da poter inserire le mie cose in esso. Non eseguirà alcuna flessibilità nell'aggiunta di articoli.

+0

è quello che sto facendo giusto? – Yasser

risposta

21

Stai vincolante il ItemsSource a una proprietà nel DataContext chiamato Items, in modo da aggiornare la raccolta, è necessario andare alla proprietà Items nel DataContext e cancellarlo.

Inoltre, la proprietà Items deve essere di tipo ObservableCollection, non List se si desidera aggiornare l'interfaccia utente ogni volta che la raccolta sottostante cambia.

Il bit di codice che imposta ItemsSource nel codice non è necessario e deve essere rimosso. Devi solo impostare ItemsSource in un unico posto, non entrambi.

Ecco un semplice esempio di come può funzionare:

// Using Students instead of Items for the PropertyName to clarify 
public ObservableCollection<Student> Students { get; set; } 

public MyConstructor() 
{ 
    ... 

    Students = search.students(); 
    listBoxSS.DataContext = this; 
} 

Ora, quando si dispone di:

<ListView ItemsSource="{Binding Students}" ... /> 

stai vincolante il ItemsSource al ObservableCollection<Student>, e quando si desidera cancellare il elenco è possibile chiamare:

Students.Clear() 
+0

grazie mille funziona ora con alcune modifiche modifico la mia domanda in modo da poter vedere cosa ho fatto – Yasser

+0

è quello che sto facendo giusto? – Yasser

1

Assegna la proprietà ItemsSource della listbox a una proprietà pubblica all'interno della classe del modulo. Quindi prova ad aggiungere una rimozione da quella, chiamando PropertyChanged all'interno del setter, invece di chiamare clear direttamente sull'origine degli elementi della lista.

+0

potresti farmi un esempio? – Yasser

3

È necessario lavorare contro la raccolta legata ai dati al numero ItemsSource. Al fine di ottenere le notifiche di modifica di raccolta (quando gli elementi vengono aggiunti o rimossi), è necessario utilizzare un ObservableCollection<T>:

var students = new ObservableCollection<Student>(search.students()); 
listBoxSS.ItemsSource = students; 

students.Clear(); 
students.Add(new Student("ABC")); 

E si dovrebbe rimuovere la dichiarazione ItemsSource="{Binding Items}" dal vostro XAML.

+0

Questo non funzionerà perché 'ItemsSource' è impostato, non vincolato. Quindi le modifiche a 'studenti' non si rifletteranno in' ListView' – Rachel

+0

@Rachel: Probabilmente hai ragione. Fammi verificare e modificare. – Douglas

+0

@Rachel: In realtà, no, le modifiche alla raccolta 'studenti' * fanno * aggiornano il' ListView'. L'unica differenza che l'associazione dati con una proprietà avrebbe apportato è che potrebbe anche generare notifiche quando un'altra * raccolta * è assegnata alla proprietà (supponendo che la classe implementi 'INotifyPropertyChanged'). – Douglas

0

Ho avuto lo stesso problema e Alla fine ho capito che stavo cercando di aggiungere un nuovo elemento direttamente a ItemsSource del controllo, piuttosto che a ObservableCollection che fungeva da ItemsSource.

Ho pensato che avrei postato questo, in quanto potrebbe aiutare gli altri wpfers dei principianti.

8

So che a questa domanda è stata data risposta circa 2 anni fa, tuttavia ho avuto anch'io questo problema e ho pensato a una possibile soluzione, che funziona. Forse questo non funziona in determinati scenari e forse sto semplicemente non vedere qualcosa, ma ha funzionato per me, così sto condividendo qui:

listView.ClearValue(ItemsControl.ItemsSourceProperty); 
listView.ItemsSource = NewSource; 

Spero sinceramente che questo aiuta qualcuno.

+0

Ha funzionato per me ed è stato un approccio molto più semplice. –

11

Strano ma vero: i seguenti tasti erranti nel mio file XAML prodotto l'errore "Operazione non è valida fino ad esaurimento ItemsSource è in uso accedere e modificare gli elementi con ItemsControl.ItemsSource invece..":

</ItemsControl.ItemTemplate>x` 

Nota i caratteri "x" dopo il tag dell'elemento di chiusura.

+5

Sì, strano ma vero: avevo scritto:> (nota doppia parentesi di chiusura) –

+0

Grazie. I personaggi extra all'interno del tag sono stati i colpevoli qui. –

+0

Ha! Nel mio caso, avevo scritto ">" invece di "/>", quindi un elemento non è mai stato chiuso. Ora, perché questo tipo di cose non viene rilevato al momento della compilazione? – redcurry

1

In ritardo per la festa, lo so, ma penso che questa risposta non sia abbastanza chiara sopra. La sua relativa ai personaggi canaglia post, ma questo fa sì che anche l'eccezione:

<ItemsControl ItemsSource="{Binding AnObservableCollection}"> 
    <Label Content="{Binding Name}"/> 
</ItemsControl> 

Quando ciò che volevi dire era:

<ItemsControl ItemsSource="{Binding AnObservableCollection}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <Label Content="{Binding Name}"/> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

La sua facile come un nuovo arrivato (o prima del primo caffè del mattino) a pensare che il la prima è corretta e l'eccezione non spiega in alcun modo cosa è sbagliato.

Problemi correlati