【问题标题】:Wpf Datagrid Max RowsWpf Datagrid 最大行数
【发布时间】:2011-06-20 22:53:51
【问题描述】:

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

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

我想知道是否有实现此功能的好方法....

感谢和问候, 凯文

【问题讨论】:

    标签: wpf datagrid wpfdatagrid


    【解决方案1】:

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

    InvalidOperationException
    'NewItemPlaceholderPosition' 不是 在开始的交易期间允许 '新增'。

    为了解决这个问题,在OnItemsChanged 中调用了一个名为IsInEditMode 的方法,如果它返回true,我们订阅事件LayoutUpdated 以再次检查IsInEditMode

    此外,如果 MaxRows 设置为 20,则当 CanUserAddRows 为 True 时,它​​必须允许 20 行,而当 False 时,它​​必须允许 19 行(为 False 时不存在的 NewItemPlaceHolder 腾出位置)。

    可以这样使用

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

    【讨论】:

      【解决方案2】:

      我是 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)

      【讨论】:

      • 当他们删除一行然后尝试添加另一行时会发生什么?
      猜你喜欢
      • 1970-01-01
      • 2011-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-20
      • 2012-12-09
      相关资源
      最近更新 更多