在Silverlight Datagrid中,如何在焦点远离Last Row时添加新行?

时间:2011-03-25 12:46:19

标签: silverlight datagrid

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

任何人都可以帮助我实现这个目标吗?

4 个答案:

答案 0 :(得分:4)

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

 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;

答案 1 :(得分:1)

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

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();
    }
}

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我将通过几个步骤揭露。所以现在就开始..

1)在此类的构造函数中声明您的事件。

this.DataGrid1.KeyDown += new KeyEventHandler(DataGrid1_KeyDown);
you also can it in XAML file.
...KeyDown="DataGrid1_KeyDown".....

2)去你的keydown活动&amp;代码。

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)现在逐行编码..

DataGridRow row = DataGridRow.GetRowContainingElement(focusedElement as FrameworkElement);
DataGridColumn column = DataGridColumn.GetColumnContainingElement(focusedElement as FrameworkElement);
TransactionMaster itemMaster = this.DataFormVoucher.CurrentItem as TransactionMaster;
decimal serialNumber = 0;
if (buttonPress == "Modify")
 if (dataGridrows - 1 == detailsDataGrid.SelectedIndex && column.DisplayIndex == 5)

TransactionChild transactionChild = new TransactionChild()"[None]",DateTime.Now.Date,catch (Exception ex)Console.WriteLine(ex.Message);

.DataGridChild.KeyDown += new KeyEventHandler(DataGridChild_KeyDown);

3)现在逐行理解代码

i)前3行用于选择数据网格的哪一行。

ii)当在这种情况下添加新行时我已经使用Tab键你也可以改变它。另外一件事是如果用户预先Tab + Shift然后它将通过(默认为控制焦点)。

iii)然后检查它是最后一行&amp;该网格的最后一列,如果是,则添加新行。否则。

iv)添加一个空白的新行只需传递你的对象(EDMX模型表)