C# WPF DataGrid-新行的事件?

C# WPF DataGrid-新行的事件?,c#,wpf,datagrid,C#,Wpf,Datagrid,我使用的是WPFDataGrid(.NET3.5SP1版本来自) 我可以订阅什么事件来检测何时添加新行?(例如,当用户向下移动光标或按Enter键时,将向网格中添加一个新的空行) 最后,我要做的是使用该事件计算一些默认值并将它们放入新行 网格被绑定到一个数据表,如果这有什么区别的话。与其在视图(网格)中处理事件,不如观察绑定的对象,并将逻辑放在那里。这使您的业务逻辑与业务对象保持一致 由于您绑定到一个数据表,最简单的方法就是订阅。当用户离开他正在编辑的行时,对象将被持久化(插入或更新)。移动到同

我使用的是WPF
DataGrid
.NET3.5SP1版本来自)

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

最后,我要做的是使用该事件计算一些默认值并将它们放入新行


网格被绑定到一个
数据表
,如果这有什么区别的话。

与其在视图(网格)中处理事件,不如观察绑定的对象,并将逻辑放在那里。这使您的业务逻辑与业务对象保持一致

由于您绑定到一个
数据表
,最简单的方法就是订阅。

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

XAML


此解决方案的所有积分归Diederik Krolls()所有。尊敬的。

您正在寻找的活动是。此事件将允许您根据需要配置新对象,然后将其应用于AddingNewItemEventArgs的NewItem属性

Xaml:


我之所以添加这一行,是因为我刚刚花了将近2个小时来研究如何让DataGrid在绑定到视图模型集合并且需要控制这些视图模型的构造时添加新行

因此,设置是,您有一个绑定到数据网格的
项源
可观察集合。您需要在视图模型层中自己创建
MyViewModel

这是DataGrid在自动添加行时的工作方式:

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

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

    添加NewItem
    不同,通过
    ItemSource
    绑定添加的项目将触发(从.Net 4.0开始提供)。

    在XAML中,在窗口标记中包含以下代码:

    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>
    
    就这些。现在,无论何时向DataGrid添加新行,都将执行LoadingRowHandlerMethod


    希望有帮助。

    我完全同意。这将给你更多的灵活性。例如,将来某一天,您可能需要一种自定义方式来添加新行,而不是使用datagrid。在本例中,所有内容都已就位,因为您只关心新对象是否已添加到集合中。。。我已经查看了DataTable RowChanged事件,但是它没有在正确的位置触发。但是TableNewRow事件确实在正确的时间触发(当生成新行时)。谢谢。在习惯行为这样的场景中,这句话是没有用的。当前正在创建一个行为,突出显示与所选行具有相同值的行(对于给定列),我不想在每一行上附加项源。我只是想指出,在.Net 4.5之前,这是不可用的,对于仍在使用.Net framework旧版本的用户。如果通过
    ItemsSource
    绑定添加项目,则不会触发
    AddingNewItem
    事件。@wondra,正确。该事件仅基于用户与网格的输入交互激发。这是基于用户与网格交互初始化新数据实例的最佳位置。从网格的角度来看,您对ItemsSource所做的任何更改都是来自您的数据存储,而不是来自用户。尝试操作ItemsSource以初始化新对象将中断用户与网格的交互。
            <DataGrid Name="GrdBallPenetrations"
                  ItemsSource="{Binding BallPenetrationCollection}" 
                  SelectedItem="{Binding CurrentSelectedBallPenetration}"
                  AutoGenerateColumns="False" 
                  IsReadOnly="False"
                  CanUserAddRows="True"
                  CanUserDeleteRows="True"
                  IsSynchronizedWithCurrentItem="True"
                  AddingNewItem="GrdBallPenetrations_AddingNewItem">
    
    private void GrdBallPenetrations_AddingNewItem(object sender, AddingNewItemEventArgs e)
        {
            e.NewItem = new BallPenetration
            {
                Id              = Guid.NewGuid(),
                CarriageWay     = CariageWayType.Plus,
                LaneNo          = 1,
                Position        = Positions.BetweenWheelTracks
            };
        }
    
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:cmd="http://www.galasoft.ch/mvvmlight"
    
    <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)
    {
      //....
      //....
    }