Wpf Datagrid Max Rows

I am currently working with a data grid where I want to allow the user to enter up to 20 rows of data before setting CanUserAddRows to false.

I created a dependency property on my own datagrid (which comes from the original). I tried to use the event " ItemContainerGenerator.ItemsChanged " and check the number of rows in it, and if row count = max rows, then do if the user can add row = false (I get an exception because I cannot change it in Add line time.

I was wondering if there is a good way to implement this ....

Thanks and Regards, Kevin

+4
source share
2 answers

Here is a subclass of DataGrid with MaxRows Dependency. It should be noted that in case the DataGrid is in edit mode and CanUserAddRows InvalidOperationException (as you mentioned in the question).

InvalidOperationException
"NewItemPlaceholderPosition" is not allowed during a transaction started by 'AddNew'.

To get around this, the IsInEditMode method in IsInEditMode is OnItemsChanged , and if it returns true, we subscribe to the LayoutUpdated event to check IsInEditMode again.

In addition, if MaxRows set to 20, it should allow 20 lines if CanUserAddRows is True and 19 lines False (to place NewItemPlaceHolder , which is not in False).

It can be used 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; } } } 
+7
source

I am an adherent K.I.S. To reduce the number of lines needed to complete the task, and save it simply, use the following:

  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 and compact; 0)

+8
source

Source: https://habr.com/ru/post/1338314/


All Articles