繁体   English   中英

WPF DataGrid - 新行的事件?

[英]WPF DataGrid - Event for New Rows?

我正在使用 WPF DataGrid工具包中的.Net 3.5 SP 1版本)

我可以订阅什么事件来检测何时添加了新行? (例如,当用户向下移动光标或按下 Enter 键时,一个新的空白行被添加到网格中)。

最终我想做的是使用该事件来计算一些默认值并将它们放在新行中。

网格绑定到DataTable ,如果这有什么不同的话。

您正在寻找的事件是DataGrid.AddingNewItem 事件 此事件将允许您配置新的对象,只要你想,然后将它应用到NewItem的财产AddingNewItemEventArgs

XAML:

<DataGrid Name="GrdBallPenetrations"
      ItemsSource="{Binding BallPenetrationCollection}" 
      SelectedItem="{Binding CurrentSelectedBallPenetration}"
      AutoGenerateColumns="False" 
      IsReadOnly="False"
      CanUserAddRows="True"
      CanUserDeleteRows="True"
      IsSynchronizedWithCurrentItem="True"
      AddingNewItem="GrdBallPenetrations_AddingNewItem">

C# 背后的代码:

private void GrdBallPenetrations_AddingNewItem(object sender,
    AddingNewItemEventArgs e)
{
    e.NewItem = new BallPenetration
    {
        Id              = Guid.NewGuid(),
        CarriageWay     = CariageWayType.Plus,
        LaneNo          = 1,
        Position        = Positions.BetweenWheelTracks
    };
}

当用户离开他正在编辑的行时,对象会被持久化(插入或更新)。 移动到同一行中的另一个单元格会通过数据绑定更新相应的属性,但尚未向模型(或数据访问层)发出信号。 唯一有用的事件是 DataGrid.RowEditEnding。 这是在提交修改后的行之前触发的。

XAML

<DataGrid ... 
          RowEditEnding="MyDataGrid_RowEditEnding">
</DataGrid>

背后的代码

private void MyDataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e) 
{    // Only act on Commit
    if (e.EditAction == DataGridEditAction.Commit)
    {
         var newItem = e.Row.DataContext as MyDataboundType;
         if (newItem is NOT in my bound collection) ... handle insertion...
    } 
}

此解决方案的所有功劳都归于 Diederik Krolls( 原帖)。 我的敬意。

我建议不要在您的视图(网格)中处理事件,而是建议您查看绑定对象,并将您的逻辑放在那里。 这使您的业务逻辑与您的业务对象保持一致

由于您绑定到DataTable ,最简单的方法是订阅DataTable.TableNewRow

我添加这个是因为我刚刚花了将近 2 个小时试图弄清楚如何在绑定到视图模型集合并且需要控制这些视图模型的构造时让 DataGrid 添加新行.

因此,设置是您有一个绑定到 DataGrid 的ItemsSourceObservableCollection<MyViewModel> 您需要在视图模型层中自己创建MyViewModel

这是 DataGrid 在自动添加行时显示的功能:

  1. 当它在底部创建那个空白行时,它会创建一个MyViewModel的新实例,它将通过调用类型的默认构造函数绑定到该行。 谁知道它为什么这样做,但是如果MyViewModel没有默认构造函数,它将无法显示该空白行。 这可能是你卡住的地方,因为你没有默认构造函数,因为你需要自己创建对象。 不幸的是,您将需要添加一个。 再次注意,如果元素类型是接口,这注定会失败。 集合的元素类型必须是具有默认构造函数的具体类。
  2. 现在它等待用户编辑该行,此时它开始适当的添加。
  3. 它引发了AddingNewItem :您可以在此处拦截添加操作并切换出它使用您自己的实例创建的默认构造函数创建的实例。 AddingNewItemEventArgs.NewItem有一个 setter,您可以将当前项目换成自己的。

我发现 DataGrid_InitializingNewItem 事件很有用,您可以在其中检查 e.NewItem 并根据其类型采取适当的操作。

AddingNewItem不同, DataGrid.LoadingRow 事件(自 .Net 4.0 起可用)将为通过ItemSource绑定添加的项目触发。

在您的 XAML 中,在您的 Window 标记中包含以下代码:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:cmd="http://www.galasoft.ch/mvvmlight"

接下来,在 DataGrid 元素中,添加以下触发器:

<DataGrid ...>

  <i:Interaction.Triggers>
        <i:EventTrigger EventName="LoadingRow">
               <cmd:EventToCommand Command="{Binding LoadRowHandler}" 
                                                PassEventArgsToCommand="True"/>
         </i:EventTrigger>                        
   </i:Interaction.Triggers>

</DataGrid>

接下来,在您的视图模型中,添加用于处理事件的命令:

public RelayCommand<DataGridRowEventArgs> LoadRowHandler{ get; private set; }

在构造函数中,初始化命令:

LoadRowHandler = new RelayCommand<DataGridRowEventArgs>(LoadingRowHandlerMethod);

接下来,创建一个方法来放置逻辑:

private void LoadingRowHandlerMethod(DataGridRowEventArgs e)
{
  //....
  //....
}

仅此而已。 现在,每当向 DataGrid 添加新行时,都会执行 LoadingRowHandlerMethod。

希望它有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM