Wpf数据表格的最大行数

5
我目前正在使用数据网格,我希望在CanUserAddRows为false之前,只允许用户输入最多20行数据。
我在自己的数据网格上创建了一个依赖属性(继承自原始数据网格)。我尝试使用事件“ItemContainerGenerator.ItemsChanged”并在其中检查行数,如果行数等于最大行数,则将CanUserAddRows设置为false(我会收到异常消息,说我不允许在“添加行”期间更改它)。
我想知道是否有一种好的实现方法...
谢谢和问候, Kevin
2个回答

8
这是一个带有 MaxRows 依赖属性的子类化 DataGrid。实现需要注意的事项是,如果 DataGrid 处于编辑模式且更改了 CanUserAddRows,则会发生 InvalidOperationException 异常(如您在问题中提到的)。

InvalidOperationException
'NewItemPlaceholderPosition' 在由 'AddNew' 开始的事务期间不被允许。

为解决此问题,在 OnItemsChanged 中调用名为 IsInEditMode 的方法,如果它返回 true,则订阅事件 LayoutUpdated 再次检查 IsInEditMode
另外,如果将 MaxRows 设置为 20,则在 CanUserAddRows 为 True 时必须允许 20 行,在 False 时必须允许 19 行(为了留出 NewItemPlaceHolder 的位置,该项在 False 时不存在)。
可以像这样使用:
<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;
        }
    }
}

8

我是K.I.S.S.的支持者。为了简化工作并让它更简单,使用以下方法:

    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;
        }
    }

简单而紧凑;0)

2
当他们删除一行然后尝试添加另一行时会发生什么? - Jon Barker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接