用户更改行时引发的DataGrid LostFocus事件

时间:2015-11-21 02:47:48

标签: wpf vb.net datagrid

以下是用于创建数据网格的XAML:

<DataGrid
            x:Name="dgrComments"
            Height="200">
            <DataGrid.Columns>
            <DataGridTextColumn
                Binding="{Binding Path=RepairID}"
                Visibility="Hidden" />
            <DataGridTextColumn
                Binding="{Binding Path=Sequence}"
                Visibility="Hidden" />
            <DataGridTextColumn
                Binding="{Binding Path=Entry}"
                DisplayIndex="0" />
            <DataGridTextColumn
                Binding="{Binding Path=LastUpdate}"
                Visibility="Hidden" />
        </DataGrid.Columns>
    </DataGrid>

以下是我将数据绑定到网格的方式(&#34; Sequence&#34;是RepairComments表中的一列):

RepairFilter=<a text string that is a valid filter>
dvComments = New DataView(dsPIM.Tables("RepairDetails"), RepairFilter, "Sequence", DataViewRowState.CurrentRows)
dgrComments.ItemsSource = dvComments

除了用户更改所选行时数据网格dgrComments.LostFocus事件正在触发之外,这一切都正常工作。为什么呢?

2 个答案:

答案 0 :(得分:3)

DataGrid.LostFocus的问题在于每次编辑单元格时都会触发它。

这并不总是坏事,因为处理单元格更新或注册单元格更改很有用。

但是,如果您想要检测用户何时将DataGrid作为一个整体留给页面上其他位置的另一个控件,那么这是烦人的。

解决方案是检测现在确切的焦点,并确定它是在DataGrid内部还是外部。

为此,我们可以使用FocusManager获取当前聚焦的元素。 然后我们只是检查父容器是否是DataGrid的一部分。

如果不是,我们知道它在DataGrid之外,这表示我们的DataGrid.LostFocus事件。

private void dgrComments_LostFocus(object sender, RoutedEventArgs e) 
{ 
    Control ctrl = FocusManager.GetFocusedElement(this) as Control;  
    if (ctrl.Parent != null && ctrl.Parent.GetType() != typeof(DataGridCell)) 
        MessageBox.Show("outside!"); 
}

改编自code.msdn.com

答案 1 :(得分:0)

具有CollectionViewSource属性的最佳解决方案

    private CollectionViewSource epairDetailsViewSource;

    private void FormItems_Loaded(object sender, RoutedEventArgs e)
    {
        repairDetailsViewSource= ((CollectionViewSource)this.FindResource("repairDetailsViewSource"));

        context = new MyDbContext();
        context.RepairDetails.Load();

        repairDetailsViewSource.Source = context.Items.Local;

        repairDetailsViewSource.View.CurrentChanging += View_CurrentChanging;
    }

    private void View_CurrentChanging(object sender, CurrentChangingEventArgs e)
    {
        ((RepairDetails)repairDetailsViewSource.View.CurrentItem).//...
    }