2009-04-12 16 views
5

Tengo un ObservableCollection enlazado a un ListBox en WPF. Quiero que el ListBox sea editable y que los cambios de edición se guarden en la colección. Como WPF no proporciona un cuadro de lista editable, intenté crear el mío cambiando el ListBox.ItemTemplate.WPF ListBox editable

<ListBox.ItemTemplate> 
    <DataTemplate>      
     <TextBox Name="EditableText" Text="{TemplateBinding Content}"/> 
    </DataTemplate> 
</ListBox.ItemTemplate> 

Cambio de la ItemTemplate me da cajas editables, pero ningún cambio en los cuadros de texto No se deje guardan en el ObservableCollection. ¿Hay alguna manera de tener un ListBox editable con enlace bidireccional?

Respuesta

8

No puede hacerlo de esta manera.

Para lograr ese tipo de truco, necesitaría que sus artículos sean "clases de soporte" que expongan una propiedad a la que puede enlazar su cuadro de texto.

Para entenderlo, imaginemos la siguiente secuencia seudo de llamadas:

class ListBox 
{ 
    Bind(Items) 
    { 
    foreach(var item in Items) 
    { 
     DataTemplate Template = LoadTemplateForItem(item.GetType()); // this is where your template get loaded 
     Template.Bind(item); //this is where your template gets bound 
    } 
    } 
} 

Su plantilla (DataTemplate con el cuadro de lista) se carga y el elemento (que supongo es una cadena en su caso) se transfieren in. En este punto, solo conoce la cadena y no puede influir en nada hacia arriba. Una vinculación bidireccional no puede influir en la recopilación porque la plantilla no sabe en qué contexto se está utilizando, por lo que no puede volver a la colección original y modificar su contenido. Para el caso, esto es lo mismo para TextBox. Si no se le da un conainer y un nombre de propiedad, no tiene ningún lugar donde "almacenar" los cambios. Esto básicamente es lo mismo que pasar una cadena a una llamada de función. La función no puede cambiar qué cadena se pasó (ignorando trucos como el paso del argumento de referencia).

Para volver a su caso, es necesario construir una colección de objetos que exponen una propiedad que contiene el valor que necesita ser editado:

public class MyDataItem 
{ 
    string Data { get; set;} 
} 

Entonces se puede vincular a su ListBox a una colección de los elementos y modifiy su datatemplate:

<ListBox.ItemTemplate> 
    <DataTemplate>            
      <TextBox Name="EditableText" Text="{Binding Data, Mode=TwoWay}"/> 
    </DataTemplate> 
</ListBox.ItemTemplate> 
+0

Tengo un problema similar, pero como soy muy nuevo con WPF no sé cómo escribir {Datos de enlace, Modo = TwoWay} si tengo una lista de cadenas y no hay una propiedad real que pueda vincularse –

+1

Usted no puedo, ese es el punto de mi respuesta ... Necesita tomar su lista de cadenas, crear una lista de objetos que contengan esas cadenas (cada objeto contiene una cadena, accesible a través de una propiedad), y mostrar esa lista secundaria en el ListBox . –

0

Enlace a una propiedad modelo, es decir, una propiedad del objeto de datos, en lugar de a una propiedad de vista como Contenido. Por ejemplo:

// model class 
public class Widget : INotifyPropertyChanged 
{ 
    public string Description { ... } 
} 

<!-- view --> 
<DataTemplate> 
    <TextBox Text="{Binding Description}" /> 
</DataTemplate> 

Nota esto no funcionará si su ItemsSource es ObservableCollection (porque no hay ninguna propiedad de unirse a).

+0

No creo que pueda enlazar directamente el texto del cuadro de texto al objeto de datos. En su ejemplo, se vincula a una sola cadena, pero mi clase tiene una colección de ellas. No puedo establecer la propiedad del texto en una lista de cadenas. –

+0

DataTemplate se repite para cada miembro de la colección Items, con el enlace establecido para ese miembro. – itowlson