2012-07-19 23 views
5

tengo la siguiente prueba de concepto:¿Es esto un error de WPF Datagrid?

ventana XAML:

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" > 
    <DataGrid.Columns> 
     <DataGridTextColumn Binding="{Binding Name}" /> 
     <DataGridTemplateColumn > 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <CheckBox IsChecked="{Binding Mode=TwoWay, Path=Enabled}" /> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 
</Window> 

Código atrás:

using System.Collections.ObjectModel; 
using System.Windows; 

namespace WpfApplication1 
{ 
public partial class MainWindow : Window 
{ 
    public ObservableCollection<Data> Items { get; private set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     this.Items = new ObservableCollection<Data>(); 
     this.DataContext = this; 
     for (int index = 0; index < 30; index++) 
     { 
      this.Items.Add(new Data() {Enabled = true }); 
     } 
    } 
} 

public class Data 
{ 
    public bool Enabled { get; set; } 
} 
} 

Ejecutar la aplicación, desactive algunas cajas en la parte superior, desplácese hacia abajo, cambiar algunos cajas de nuevo y desplazarse hacia arriba. Voilá, ¡las casillas de verificación se revisan nuevamente!

¿Me falta algo o debo completar un error en Microsoft?

EDIT: Gracias por sus respuestas, pero no está relacionado con el INotify o la casilla de verificación, con un TextBox y el INotify pasa lo mismo. No es necesario que haga clic en las casillas de verificación después de desplazarse, simplemente desmarque algunos, desplácese hacia abajo, desplácese hacia arriba y listo, se verifican de nuevo. Marque este código:

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" > 
    <DataGrid.Columns> 
     <DataGridTemplateColumn > 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <CheckBox IsChecked="{Binding Mode=TwoWay, Path=Enabled}" /> 
         <TextBox Text="{Binding Text}" /> 
        </StackPanel> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 
</Window> 

Y el código subyacente:

using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Windows; 

namespace WpfApplication1 
{ 
public partial class MainWindow : Window 
{ 
    public ObservableCollection<Data> Items { get; private set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     this.Items = new ObservableCollection<Data>(); 
     this.DataContext = this; 
     for (int index = 0; index < 30; index++) 
     { 
      this.Items.Add(new Data() { Enabled = true, Text = index.ToString() }); 
     } 
    } 
} 

public class Data : INotifyPropertyChanged 
{ 
    private bool _enabled; 
    public bool Enabled 
    { 
     get { return _enabled; } 
     set 
     { 
      if (value != _enabled) 
      { 
       _enabled = value; 
       this.OnPropertyChanged("Enabled"); 
      } 
     } 
    } 

    private string _text; 
    public string Text 
    { 
     get { return _text; } 
     set 
     { 
      if (value != _text) 
      { 
       _text = value; 
       this.OnPropertyChanged("Text"); 
      } 
     } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string name) 
    { 
     if (this.PropertyChanged != null) 
     { 
      this.PropertyChanged(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

    #endregion 
} 
} 
+1

¿Su resultado cambia si hace que 'Data' herede de' INotifyPropertyChanged' y usa las notificaciones de cambio de propiedad? – Rachel

+0

Intente desactivar el reciclaje. ¿El conjunto se llama? Si no es UpdateSourceTrigger = "PropertyChanged". Y INotify como Rachel dijo. – Paparazzi

+0

Probaría lo que sugirió Rachel. – ecMode

Respuesta

1

Finalmente he introducido un defecto en Microsoft porque esta no es la forma esperada de trabajar donde quiera o no son VirtualRows usado.

Informe de error here

6

Este problema no está relacionado con el reciclaje. De hecho, deshabilitar el reciclaje oculta el problema real: sus propiedades de objeto Data nunca se actualizan. Intente establecer un punto de interrupción en el ajustador Enabled o Text y verá que no sucederá nada cuando cambie el texto o marque/desmarque la casilla. Cuando se desplaza hacia atrás y hacia atrás, la propiedad se vuelve a leer desde el objeto y, como no ha cambiado, la casilla de verificación se ha actualizado correctamente para que coincida con la propiedad Enabled.

A DataGrid está destinado a tener todas las filas en modo de visualización de manera predeterminada, con el usuario cambiando al modo de edición en la fila seleccionada actualmente cuando lo necesita. Los valores no se comprometen hasta que el usuario valida la fila completa.

Detrás de escena, se crea un implícito BindingGroup para toda la fila, estableciendo efectivamente todas las vinculaciones en UpdateSourceTrigger.Explicit. Este grupo vinculante se confirma cuando el usuario finaliza la edición de la fila. En su caso, ya que no hay BeginEdit, no habrá ningún CommitEdit y los valores nunca se actualizarán.

usted tiene varias soluciones aquí:

  • utilizar otro control que no tienen este "interruptor para modificar el modo de" comportamiento, como un ListView.
  • Fuerce UpdateSourceTrigger a PropertyChanged o LostFocus en cada encuadernación.
  • Cambie cómo el usuario usa la cuadrícula para cumplir con el comportamiento DataGrid.