2012-06-18 135 views
16

Soy nuevo en la unión y WPF recientemente he aprendido cómo crear un listBox con varias columnas usando tecnología de encuadernaciónLa operación no es válida mientras ItemsSource está en uso. elementos de acceso y modificar con ItemsControl.ItemsSource lugar

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

y este es el código:

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

pero el problema fue cuando traté de usar añadir o eliminar elemento o clara

listBoxSS.Items.Clear(); 

favor me necesito un ejemplo para usar la fuente de los elementos o la forma en que puedo AGREGAR o quitar un elemento o borrar la lista.

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> 

y aquí está el código:

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

search.employees() obtener la lista de todos los empleados en mi DB

listBoxPE.ItemsSource = employees; 
     Gemployees = employees; 

ahora puedo realizar todas los métodos en Gemployees

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

¡El ListView realiza una actualización cada vez que agrego o quito un artículo de Gemployees! Fresco, pero aún un poco de trabajo duro en la unión. Ahora estoy haciendo una clase de interfaz para cada ListView, así puedo incluir mis cosas. No realizará ninguna flexibilidad en la adición de elementos.

+0

es lo que estoy haciendo ¿verdad? – Yasser

Respuesta

21

Estás unión del ItemsSource a una propiedad en el DataContextItems llamada, por lo que para actualizar la colección, tiene que ir a la propiedad Items en el DataContext y desactivarla.

Además, la propiedad Items tiene que ser de tipo ObservableCollection, no List si lo desea para actualizar la interfaz de usuario siempre que cambia la colección subyacente.

Su código de bit que establece ItemsSource en el código no es necesario y debe eliminarse. Solo necesita configurar el ItemsSource en un solo lugar, no en ambos.

He aquí un ejemplo sencillo de cómo se puede trabajar:

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

public MyConstructor() 
{ 
    ... 

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

Ahora, cuando usted tiene:

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

que estés unión del ItemsSource a la ObservableCollection<Student>, y cuando se quiere borrar la lista puede llamar:

Students.Clear() 
+0

muchas gracias es trabajo ahora con algunos cambios Voy a Editar mi pregunta para que pueda ver lo que he hecho – Yasser

+0

es lo que estoy haciendo ¿verdad? – Yasser

1

Asigne la propiedad ItemsSource del cuadro de lista a una propiedad pública dentro de la clase del formulario. Luego, intente agregar una eliminación de eso, llamando a PropertyChanged dentro del setter, en lugar de invocar borrar directamente en el origen de elementos de la lista.

+0

¿podría darme un ejemplo? – Yasser

3

Debe trabajar contra la colección que está vinculada a su ItemsSource datos. Con el fin de obtener notificaciones de cambio de colección (cuando los artículos se añaden o se quitan), se debe utilizar un ObservableCollection<T>:

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

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

Y debe eliminar la declaración de su ItemsSource="{Binding Items}" XAML.

+0

Esto no funcionará porque 'ItemsSource' está establecido, no enlazado. Por lo tanto, los cambios en 'students' no se reflejarán en' ListView' – Rachel

+0

@Rachel: Probablemente tenga razón. Déjame verificar y editar. – Douglas

+0

@Rachel: En realidad, no, los cambios en la colección 'students' * do * actualizan' ListView'. La única diferencia que habría supuesto el enlace de datos a una propiedad es que también podría generar notificaciones cuando se asigna otra * colección * a la propiedad (suponiendo que la clase implemente 'INotifyPropertyChanged'). – Douglas

0

Tuve este mismo problema, y Finalmente me di cuenta de que estaba tratando de agregar un nuevo elemento directamente a ItemsSource del control, en lugar de a ObservableCollection que sirvió como ItemsSource.

Pensé en publicar esto, ya que podría ayudar a otras wff novatas.

8

Sé que esta pregunta ha sido respondida hace aproximadamente 2 años; sin embargo, yo también tuve este problema y pensé en una posible solución, que funciona. Tal vez esto no funciona en ciertos escenarios y quizás estoy simplemente no ver algo, pero funcionó para mí, así que estoy compartiendo aquí:

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

Sinceramente espero que esto ayude a alguien.

+0

Funcionó para mí y era un enfoque mucho más simple. –

11

Extraño pero cierto: las siguientes teclas errantes en mi archivo XAML producido el error "Operación no es válida mientras está en uso ItemsSource acceder y modificar los elementos con ItemsControl.ItemsSource lugar..":

</ItemsControl.ItemTemplate>x` 

Nota los caracteres "x`" después de la etiqueta del elemento de cierre.

+5

Sí, extraño pero cierto: escribí lo siguiente:> (tenga en cuenta el doble soporte de cierre) –

+0

Gracias. Los caracteres adicionales dentro de la etiqueta fueron los culpables aquí. –

+0

¡Ja! En mi caso, escribí ">" en lugar de "/>", por lo que un elemento nunca se cerró. Ahora, ¿por qué no se detecta este tipo de cosas en el momento de la compilación? – redcurry

1

Tarde en la fiesta que conozco, pero creo que esta respuesta no está del todo clara arriba. Su relación con los personajes sin escrúpulos Post, pero esto también hace que la excepción:

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

Cuando lo que quería decir era:

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

su fácil como un recién llegado (o antes del primer café de la mañana) a pensar que el primero es correcto y la excepción de ninguna manera explica lo que está mal.

Cuestiones relacionadas