2009-04-30 42 views
17

Estoy buscando crear un ListView editable en una aplicación C# winforms donde un usuario puede hacer doble clic en una celda para cambiar su contenido. Sería genial si alguien pudiera proporcionarle alguna guía y/o un ejemplo. No estoy buscando usar ningún producto comercial.Editable ListView

+0

Su pregunta puede ser respondida aquí: [C#: ¿Cómo editar los elementos y subelementos en una vista de lista?] [1] [1]: http://stackoverflow.com/questions/471859/ c-how-do-you-edit-items-and-subitems-in-a-listview –

+0

No estaría de acuerdo en que no deberíamos mirar alternativas de ListView como DataGridView, ObjectListView o incluso soluciones comerciales como [esto] (http: // 10tec.com/articles/editable-listview-replacement.aspx), que es lo suficientemente barato. Implementar el conocido enfoque con el editor de cuadro de texto sobre elementos/submenús ListView tiene muchos inconvenientes que debe resolver usted mismo. Por ejemplo, debe proporcionar una buena interfaz de teclado para editar subelementos, el cuadro de texto debe desplazarse junto con el ListView, etc. Usar una buena solución de terceros puede ahorrar horas de codificación y, en última instancia, incluso puede ganar más. – TecMan

Respuesta

14

usted está haciendo la pregunta equivocada :)

un ListView no es el correcto control. Use el control DataGridView. Se puede configurar para parecerse a un ListView, pero admite la edición in situ de las celdas.

+4

Esa es una cuestión de opinión. El DataGridView no siempre se ajusta al escenario de uso o proporciona la apariencia necesaria. Sin embargo, es una alternativa posible, según los objetivos del PO. –

+7

No puede hacer vistas agrupadas con DataGridView. Además de una serie de otras características que solo admite un ListView. – code4life

6

Un ObjectListView hará exactamente eso y mucho más. Es un contenedor alrededor de .NET ListView normal. Es de código abierto.

Su sitio web tiene un Getting Started para ayudarle a comenzar, así como una página entera dedicada a cell editing

+1

Gracias por su respuesta. Este control personalizado parece interesante, pero puede ser excesivo para lo que estoy tratando de hacer. Voy a experimentar con eso de todos modos. –

+3

En realidad, no es un control personalizado realmente. Es solo una envoltura útil alrededor de un ListView simple. Pero no le diremos a nadie que :) – Grammarian

+1

También podría no ser una licencia adecuada para todos los proyectos (ya que parece estar bajo GPLv3) –

0

DataGridView es su amigo SourceGrid es alternativa

1

Se podría utilizar el evento de DoubleClick de la vista de lista, y cuando se se llama, abriría un nuevo formulario donde el usuario ingresaría un nuevo valor para el elemento seleccionado. Luego, cuando el usuario haya presionado ok, editará el valor del elemento específico según lo ingresado por el usuario.

-1

Puede usar un DataTemplate para especificar que la columna contenga un cuadro de texto (si es editable) o un bloque de texto (si no se puede editar) vincula el cuadro de texto a la propiedad de clase de su colección de objetos fuente.

<Window.Resources> 
    <ResourceDictionary> 
     <DataTemplate x:Key="NameHeader"> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="Name" VerticalAlignment="Center" Margin="10,0,0,0" /> 
      </StackPanel> 
     </DataTemplate> 
     <DataTemplate x:Key="NameCell"> 
      <StackPanel Orientation="Horizontal"> 
       <TextBox Text="{Binding Path=Name}" VerticalAlignment="Center" Margin="10,0,0,0" /> 
      </StackPanel> 
     </DataTemplate> 
    </ResourceDictionary> 
</Window.Resources> 

<Grid> 
    <ListView x:Name="lvwList" Height="200" VerticalAlignment="Top" ItemsSource="{Binding Path=SourceObjectCollection}"> 
     <ListView.View> 
      <GridView> 
       <GridViewColumn Header="Name" HeaderTemplate="{StaticResource NameHeader}" CellTemplate="{StaticResource NameCell}" Width="140" /> 
      </GridView> 
     </ListView.View> 
    </ListView> 
</Grid> 

Nick Hanshaw

+6

Bienvenido a SO, Nick. Esta es una buena respuesta, pero desafortunadamente la pregunta está etiquetada como 'winforms', no' wpf'. –

-1

Recientemente me encontré con este problema. Después de tomar la sugerencia de Simon Gillbee de que es posible configurar DataGridView para que parezca mucho a ListView, busqué una solución sensata para lograr eso. El siguiente código funcionó bien para mí. Source here.

class GridLineDataGridView : DataGridView 
{ 
    public GridLineDataGridView() 
    { 
     this.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     int rowHeight = this.RowTemplate.Height; 

     int h = this.ColumnHeadersHeight + rowHeight * this.RowCount; 
     int imgWidth = this.Width - 2; 
     Rectangle rFrame = new Rectangle(0, 0, imgWidth, rowHeight); 
     Rectangle rFill = new Rectangle(1, 1, imgWidth - 2, rowHeight); 
     Rectangle rowHeader = new Rectangle(2, 2, this.RowHeadersWidth - 3, rowHeight); 

     Pen pen = new Pen(this.GridColor, 1); 

     Bitmap rowImg = new Bitmap(imgWidth, rowHeight); 
     Graphics g = Graphics.FromImage(rowImg); 
     g.DrawRectangle(pen, rFrame); 
     g.FillRectangle(new SolidBrush(this.DefaultCellStyle.BackColor), rFill); 
     g.FillRectangle(new SolidBrush 
      (this.RowHeadersDefaultCellStyle.BackColor), rowHeader); 

     int w = this.RowHeadersWidth - 1; 
     for (int j = 0; j < this.ColumnCount; j++) 
     { 
      g.DrawLine(pen, new Point(w, 0), new Point(w, rowHeight)); 
      w += this.Columns[j].Width; 
     } 

     int loop = (this.Height - h)/rowHeight; 
     for (int j = 0; j < loop + 1; j++) 
     { 
      e.Graphics.DrawImage(rowImg, 1, h + j * rowHeight); 
     } 
    } 
} 

Sólo heredan de DataGridView y reemplazar el método OnPaint.

Puede cambiar las diversas propiedades del control según sus necesidades y preferencias.

Para aquellos que necesitan ayuda con la incorporación de un control personalizado en su aspecto de proyecto here.

+0

El ejemplo está incompleto. Para los nuevos en WPF, ¿dónde colocas el nuevo DataGrid? –

+0

@CJohnson: esta pregunta es sobre WinForms y ** no ** WPF. Por favor, compruebe la etiqueta de pregunta y el contexto. –

0

Sí, use un DataGridView.

No solo puede editar una celda, pero si declara una lista genérica donde T es la clase que desea mostrar en la cuadrícula, puede establecer DataSource = esa lista y mientras edita la vista de cuadrícula, en realidad está editando la lista automágicamente!