ejemplos - Wpf Datagrid Max Filas
selecteditems datagrid c# (2)
Actualmente estoy trabajando con la cuadrícula de datos donde solo quiero permitir que el usuario ingrese hasta 20 filas de datos antes de hacer que CanUserAddRows sea falso.
Hice una propiedad de dependencia en mi propia cuadrícula de datos (que se deriva de la original). Intenté usar el evento " ItemContainerGenerator.ItemsChanged
" y verifiqué el recuento de filas allí y si el recuento de filas = máx. Filas, luego puedo hacer que el usuario agregue row = false (obtengo una excepción por eso diciendo que no me permite cambiarlo durante "Añadir fila".
Me preguntaba si hay una buena manera de implementar esto ...
Gracias y saludos, Kevin
Aquí hay un DataGrid
subclasificado con una propiedad de dependencia de MaxRows
. Lo que debe tener en cuenta sobre la implementación es que si DataGrid
está en modo de edición y CanUserAddRows
se cambia, se producirá una InvalidOperationException
(como usted mencionó en la pregunta) .
InvalidOperationException
''NewItemPlaceholderPosition'' no está permitido durante una transacción iniciada por ''AddNew''.
Para solucionar este problema, se llama a un método llamado IsInEditMode
en OnItemsChanged
y si devuelve true nos suscribimos al evento LayoutUpdated
para LayoutUpdated
a comprobar IsInEditMode
.
Además, si MaxRows
se establece en 20, debe permitir 20 filas cuando CanUserAddRows
es True y 19 filas cuando es False (para hacer lugar para NewItemPlaceHolder
que no está presente en False).
Se puede usar así
<local:MaxRowsDataGrid MaxRows="20"
CanUserAddRows="True"
...>
MaxRowsDataGrid
public class MaxRowsDataGrid : DataGrid
{
public static readonly DependencyProperty MaxRowsProperty =
DependencyProperty.Register("MaxRows",
typeof(int),
typeof(MaxRowsDataGrid),
new UIPropertyMetadata(0, MaxRowsPropertyChanged));
private static void MaxRowsPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
MaxRowsDataGrid maxRowsDataGrid = source as MaxRowsDataGrid;
maxRowsDataGrid.SetCanUserAddRowsState();
}
public int MaxRows
{
get { return (int)GetValue(MaxRowsProperty); }
set { SetValue(MaxRowsProperty, value); }
}
private bool m_changingState;
public MaxRowsDataGrid()
{
m_changingState = false;
}
protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
if (IsInEditMode() == true)
{
EventHandler eventHandler = null;
eventHandler += new EventHandler(delegate
{
if (IsInEditMode() == false)
{
SetCanUserAddRowsState();
LayoutUpdated -= eventHandler;
}
});
LayoutUpdated += eventHandler;
}
else
{
SetCanUserAddRowsState();
}
}
private bool IsInEditMode()
{
IEditableCollectionView itemsView = Items;
if (itemsView.IsAddingNew == false && itemsView.IsEditingItem == false)
{
return false;
}
return true;
}
// This method will raise OnItemsChanged again
// because a NewItemPlaceHolder will be added or removed
// so to avoid infinite recursion a bool flag is added
private void SetCanUserAddRowsState()
{
if (m_changingState == false)
{
m_changingState = true;
int maxRows = (CanUserAddRows == true) ? MaxRows : MaxRows-1;
if (Items.Count > maxRows)
{
CanUserAddRows = false;
}
else
{
CanUserAddRows = true;
}
m_changingState = false;
}
}
}
Soy un experto en KISS Para reducir la cantidad de líneas requeridas para hacer el trabajo y mantenerlo simple, use lo siguiente:
private void MyDataGrid_LoadingRow( object sender, DataGridRowEventArgs e )
{
// The user cannot add more rows than allowed
IEditableCollectionView itemsView = this.myDataGrid.Items;
if( this.myDataGrid.Items.Count == max_RowCount + 1 && itemsView.IsAddingNew == true )
{
// Commit the current one added by the user
itemsView.CommitNew();
// Once the adding transaction is commit the user cannot add an other one
this.myDataGrid.CanUserAddRows = false;
}
}
Simple y compacto; 0)