Wpf Datagrid Max Rows

Kev*_*v84 5 wpf datagrid wpfdatagrid

我目前正在使用数据网格,我只想让用户在将CanUserAddRows设置为false之前输入最多20行数据.

我在自己的数据网格上创建了​​一个依赖属性(源自原始数据网格).我尝试使用事件" ItemContainerGenerator.ItemsChanged"并检查那里的行数,如果行计数=最大行数,那么make可以用户添加row = false(我得到一个例外,说我不允许在"添加行"期间更改它".

我想知道是否有一个很好的方法来实现这个....

谢谢和问候,凯文

小智 8

我是KISS的擅长为了减少完成工作所需的行数并保持简单,请使用以下内容:

    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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

简单紧凑; 0)

  • 当他们删除一行然后尝试添加另一行时会发生什么? (2认同)

Fre*_*lad 7

这是一个DataGrid带有MaxRows依赖属性的子类.关于实现的注意事项是,如果DataGrid处于编辑模式并且CanUserAddRows发生了更改,InvalidOperationException则会发生(就像您在问题中提到的那样).


在'AddNew'开始的事务期间,不允许使用InvalidOperationException'NewItemPlaceholderPosition '.

要解决这一点,调用的方法IsInEditMode被调用OnItemsChanged,如果返回true,我们订阅事件LayoutUpdated来检查IsInEditMode一次.

另外,如果MaxRows设置为20,则当CanUserAddRows为True 时必须允许20行,当False 时必须允许19行(为False时NewItemPlaceHolder不存在的行).

它可以像这样使用

<local:MaxRowsDataGrid MaxRows="20"
                       CanUserAddRows="True"
                       ...>
Run Code Online (Sandbox Code Playgroud)

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)