【问题标题】: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)