2011-04-15 12 views
5

Tengo un tabControl. En uno de los tabitem tengo un usercontrol que contiene una cuadrícula de datos que tiene CanUserAddRows = "True". El usuario puede escribir datos en la columna y presiona ingresar; se crea una nueva fila (supongo que la cuadrícula de datos hace esto porque CanUserAddRows = "True"). El problema es que cuando escribo los datos y cambio las pestañas recibo esta excepción "WPF datagrid 'newitemplaceholderposition' no está permitido durante una transacción iniciada por 'Addnew'"WPF datagrid 'newitemplaceholderposition' no está permitido durante una transacción iniciada por 'addnew'

¿Alguna sugerencia de cómo evitarlo?

He intentado poner dg.CommitEdit() en usercontrol.unloaded(). No recibo la excepción, pero no obtengo la nueva fila.

Respuesta

3

Me encontré con el mismo problema ... aquí hay algunos fragmentos que describen cómo lo resolví. Tenga en cuenta que en mi caso quería rechazar los cambios para evitar el error. Si desea comprometer los cambios, esto puede llevarlo en la dirección correcta.

1a) Use el evento InitializingNewItem en la cuadrícula de datos para capturar la fila de adición.

private void mydatagrid_InitializingNewItem(object sender, InitializingNewItemEventArgs e) 
    { 
     _viewmodel.NewRowDefaults((DataRowView)e.NewItem); 
    } 

1b) En este caso, voy a llamar a un método en mi modelo de vista para rellenar los valores predeterminados de fila y guardar una referencia a la fila.

private DataRowView _drvAddingRow { get; set; } 
    public void NewRowDefaults(DataRowView drv) 
    { 
     _drvAddingRow = drv; 
     ... 
    } 

2) A continuación, cuando se necesita para rechazar el cambio (antes de notificar los cambios de propiedad o lo que su caso es), utilice el método CancelEdit en el DataRowView capturado.

_drvAddingRow.CancelEdit(); 
3

Acabo de encontrarme con el mismo problema. Se encontraron dos soluciones posibles:

1/Dispare el evento CommitEdit del DataGrid, luego llame a CommitEdit. No estoy seguro de por qué se necesita este último paso, es posible que no tenga que llamar a CommitEdit en su caso.

 DataGrid.CommitEditCommand.Execute(this.DataGridWorkItems, this.DataGridWorkItems); 

     yourDataGrid.CommitEdit(DataGridEditingUnit.Row, false); 

2/Simular un golpe en la tecla de retorno del teclado:

 var keyEventArgs = new KeyEventArgs(InputManager.Current.PrimaryKeyboardDevice,PresentationSource.FromDependencyObject(yourDataGrid), System.Environment.ProcessorCount, Key.Return); 
     keyEventArgs.RoutedEvent = UIElement.KeyDownEvent; 
     yourDataGrid.RaiseEvent(keyEventArgs); 

me conformé con la última solución, ya que tenía unos efectos secundarios a pescado con el primero.

0

He utilizado la respuesta de holmes pero no funcionó bien para mí. Así que cambié un poco.

Aquí está mi solución:

En primer lugar, debido a que estoy usando MVVM, añadí este los códigos de la cuadrícula de datos:

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="InitializingNewItem"> 
     <ei:CallMethodAction TargetObject="{Binding}" MethodName="OnDataGridInitializingNewItem"/> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

Los espacios de nombres son los siguientes:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 

Luego, agregué este código al ViewModel y establecí el DataGrid:

private DataGrid _dg { get; set; } 

public void OnDataGridInitializingNewItem(object sender, InitializingNewItemEventArgs e) 
{ 
    if (_dg == null) 
     _dg = (DataGrid)sender; 
} 

Después de todo, cuando es necesario, me encontré con este código:

_dg.CommitEdit(); 

Por último funciona muy bien :)

PS: En primer lugar, había intentado método CancelEdit en lugar de CommitEdit. Funcionó y fui a otra vista que se abrió como una ventana emergente. Cuando terminé qué hacer y volví a la vista, la última fila añadida había desaparecido. Pero estaba comprometido con el db. Después de volver a abrir la vista, estaba allí.