在Silverlight Datagrid中,当焦点离开最后一行时,如何添加新行?

在Silverlight Datagrid中,当焦点离开最后一行时,如何添加新行?,silverlight,datagrid,Silverlight,Datagrid,我想在我的Silverlight DataGrid中添加一个新行,当用户尝试按Tab/Enter键从最后一行转到下一行时,DataGrid会失去焦点。我不能使用RowEditEnded事件,因为即使我从LastRow移动到上一行,它也会触发 有人能帮我实现这一点吗?您可以使用路由事件概念,其中捕获Enter/Tab键,您可以向数据网格控件添加新行。您可以使用路由事件概念,其中捕获Enter/Tab键,您可以向数据网格控件添加新行。如果查看DataGrid源代码,您可以看到它会捕获按键事件f.i.

我想在我的Silverlight DataGrid中添加一个新行,当用户尝试按Tab/Enter键从最后一行转到下一行时,DataGrid会失去焦点。我不能使用RowEditEnded事件,因为即使我从LastRow移动到上一行,它也会触发


有人能帮我实现这一点吗?

您可以使用路由事件概念,其中捕获Enter/Tab键,您可以向数据网格控件添加新行。

您可以使用路由事件概念,其中捕获Enter/Tab键,您可以向数据网格控件添加新行。

如果查看DataGrid源代码,您可以看到它会捕获按键事件f.i.,以实现按下enter键后转到下一行的功能。作为解决方案,我建议实现从DataGrid继承的自己的网格,并添加当用户按下EnterOther按钮时引发的事件。自身控制:

 public class MyDataGrid : DataGrid
 {
        public event EventHandler OnLastRowEnterPressed;

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
                if (ItemsSource != null 
&& ItemsSource.Cast<object>().Count() - 1 == SelectedIndex 
&& e.Key == Key.Enter)
            {
                RaiseLastRowEnterPressed();
            }
        }

        private void RaiseLastRowEnterPressed()
        {
            if (OnLastRowEnterPressed != null)
                OnLastRowEnterPressed(this, EventArgs.Empty);
        }
 }
使用:

ObservableCollection<Foo> source = new ObservableCollection<Foo>()
                                  {
                                      new Foo(), new Foo(), new Foo(),
                                  };
myDataGrid.OnLastRowEnterPressed += (s, e) => source.Add(new Foo());
myDataGrid.ItemsSource = source;

若你们看一下DataGrid的源代码,你们会发现它捕获了按键事件f.i.,以实现类似按下enter键进入下一行的功能。作为解决方案,我建议实现从DataGrid继承的自己的网格,并添加当用户按下EnterOther按钮时引发的事件。自身控制:

 public class MyDataGrid : DataGrid
 {
        public event EventHandler OnLastRowEnterPressed;

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
                if (ItemsSource != null 
&& ItemsSource.Cast<object>().Count() - 1 == SelectedIndex 
&& e.Key == Key.Enter)
            {
                RaiseLastRowEnterPressed();
            }
        }

        private void RaiseLastRowEnterPressed()
        {
            if (OnLastRowEnterPressed != null)
                OnLastRowEnterPressed(this, EventArgs.Empty);
        }
 }
使用:

ObservableCollection<Foo> source = new ObservableCollection<Foo>()
                                  {
                                      new Foo(), new Foo(), new Foo(),
                                  };
myDataGrid.OnLastRowEnterPressed += (s, e) => source.Add(new Foo());
myDataGrid.ItemsSource = source;

弗拉基米尔,似乎没有简单/直接的方法在最后一行退出后添加新行。您的解决方案将起作用,但在其他按键事件中引发事件的后果也是如此。我想出了各种事件的组合来获得解决方案

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);
    addFlag = (e.Key == Key.Tab);
}

protected override void OnLostFocus(RoutedEventArgs e)
{
    addFlag = (addFlag && true); 
    base.OnLostFocus(e);
}

protected override void OnRowEditEnded(DataGridRowEditEndedEventArgs e)
{
    base.OnRowEditEnded(e);
    addFlag = (addFlag && IsLastRowSelected);
    if (addFlag)
        AddItem();
    addFlag = false;
}

protected override void OnKeyUp(KeyEventArgs e)
{            
    base.OnKeyUp(e);
    addFlag = false;
}

protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
    base.OnSelectionChanged(e);
    addFlag = false;
}

private void AddItem()
{
    if (RaiseAddEvent!= null)
    {
        this.Focus();
        RaiseAddEvent(this, EventArgs.Empty);
        this.UpdateLayout();
        this.CurrentColumn = this.Columns[0];
        this.BeginEdit();
    }
}

弗拉基米尔,似乎没有简单/直接的方法在最后一行退出后添加新行。您的解决方案将起作用,但在其他按键事件中引发事件的后果也是如此。我想出了各种事件的组合来获得解决方案

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);
    addFlag = (e.Key == Key.Tab);
}

protected override void OnLostFocus(RoutedEventArgs e)
{
    addFlag = (addFlag && true); 
    base.OnLostFocus(e);
}

protected override void OnRowEditEnded(DataGridRowEditEndedEventArgs e)
{
    base.OnRowEditEnded(e);
    addFlag = (addFlag && IsLastRowSelected);
    if (addFlag)
        AddItem();
    addFlag = false;
}

protected override void OnKeyUp(KeyEventArgs e)
{            
    base.OnKeyUp(e);
    addFlag = false;
}

protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
    base.OnSelectionChanged(e);
    addFlag = false;
}

private void AddItem()
{
    if (RaiseAddEvent!= null)
    {
        this.Focus();
        RaiseAddEvent(this, EventArgs.Empty);
        this.UpdateLayout();
        this.CurrentColumn = this.Columns[0];
        this.BeginEdit();
    }
}

我将通过几步来揭露。那么,让我们现在开始

1在该类的构造函数中删除事件

this.DataGrid1.KeyDown += new KeyEventHandler(DataGrid1_KeyDown);
you also can it in XAML file.
...KeyDown="DataGrid1_KeyDown".....
2.进入按键事件并编写代码

var focusedElement = FocusManager.GetFocusedElement();
DataGrid detailsDataGrid = sender as DataGrid;
int dataGridrows = detailsDataGrid.ItemsSource.OfType<object>().Count();
if (e.Key == Key.Tab && (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
return;
if (e.Key == Key.Tab)
try
{
detailsDataGrid.SelectedIndex = row.GetIndex();
{

itemMaster.TransactionChilds.Add(transactionChild);
detailsDataGrid.SelectedItem = transactionChild;
}
}
3现在逐行理解代码

i前3行用于选择datagrid的哪一行

当添加新行时,在这种情况下,我使用了Tab键,您也可以更改它。另一件事是,如果用户predd Tab+Shift,那么它将作为默认控件焦点

iii然后检查是否为该网格的最后一行和最后一列,如果是,则添加新行或其他


iv要添加一个空白新行,只需传递对象EDMX模型表即可

我将通过几个步骤公开。那么,让我们现在开始

1在该类的构造函数中删除事件

this.DataGrid1.KeyDown += new KeyEventHandler(DataGrid1_KeyDown);
you also can it in XAML file.
...KeyDown="DataGrid1_KeyDown".....
2.进入按键事件并编写代码

var focusedElement = FocusManager.GetFocusedElement();
DataGrid detailsDataGrid = sender as DataGrid;
int dataGridrows = detailsDataGrid.ItemsSource.OfType<object>().Count();
if (e.Key == Key.Tab && (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
return;
if (e.Key == Key.Tab)
try
{
detailsDataGrid.SelectedIndex = row.GetIndex();
{

itemMaster.TransactionChilds.Add(transactionChild);
detailsDataGrid.SelectedItem = transactionChild;
}
}
3现在逐行理解代码

i前3行用于选择datagrid的哪一行

当添加新行时,在这种情况下,我使用了Tab键,您也可以更改它。另一件事是,如果用户predd Tab+Shift,那么它将作为默认控件焦点

iii然后检查是否为该网格的最后一行和最后一列,如果是,则添加新行或其他


iv要添加一个空白新行,只需传递对象EDMX模型表即可

弗拉基米尔,似乎没有简单/直接的方法在最后一行退出后添加新行。上述解决方案将起作用,但在其他关键新闻事件中也会引发事件的后果。我不能将整个解决方案作为评论评论长度验证,我已将其作为以下答案。在“按键”检查中,当我使用“回车”键时,我的日志中没有“回车”键。弗拉基米尔,似乎没有简单/直接的方法在最后一行退出后添加新行。上述解决方案将起作用,但在其他关键新闻事件中也会引发事件的后果。我不能将整个解决方案作为评论评论长度验证,我已将其作为以下答案。在“按键”检查中,当我使用“回车”键时,我的日志中没有“回车”键。