Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's a subclassed <code>DataGrid</code> with a <code>MaxRows</code> Dependency Property. The things to note about the implementation is if the <code>DataGrid</code> is in edit mode and <code>CanUserAddRows</code> is changed an <code>InvalidOperationException</code> will occur <em>(like you mentioned in the question)</em>.</p> <blockquote> <p><strong>InvalidOperationException</strong><br> 'NewItemPlaceholderPosition' is not allowed during a transaction begun by 'AddNew'.</p> </blockquote> <p>To workaround this, a method called <code>IsInEditMode</code> is called in <code>OnItemsChanged</code> and if it returns true we subscribe to the event <code>LayoutUpdated</code> to check <code>IsInEditMode</code> again.</p> <p>Also, if <code>MaxRows</code> is set to 20, it must allow 20 rows when <code>CanUserAddRows</code> is True, and 19 rows when False (to make place for the <code>NewItemPlaceHolder</code> which isn't present on False).</p> <p>It can be used like this</p> <pre><code>&lt;local:MaxRowsDataGrid MaxRows="20" CanUserAddRows="True" ...&gt; </code></pre> <p><strong>MaxRowsDataGrid</strong></p> <pre><code>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 &amp;&amp; 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 &gt; maxRows) { CanUserAddRows = false; } else { CanUserAddRows = true; } m_changingState = false; } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload