我想在我的Silverlight DataGrid中添加一個新行,當用戶嘗試通過Tab/Enter從LastRow到NextRow(因爲它的最後一行,DataGrid失去焦點)。我不能使用RowEditEnded事件,因爲即使我從LastRow移動到PreviousRow,它也會觸發。在Silverlight Datagrid中,如何在焦點離開最後一行時添加新行?
任何人都可以幫助我實現這個目標嗎?
我想在我的Silverlight DataGrid中添加一個新行,當用戶嘗試通過Tab/Enter從LastRow到NextRow(因爲它的最後一行,DataGrid失去焦點)。我不能使用RowEditEnded事件,因爲即使我從LastRow移動到PreviousRow,它也會觸發。在Silverlight Datagrid中,如何在焦點離開最後一行時添加新行?
任何人都可以幫助我實現這個目標嗎?
如果你看看DataGrid的源代碼,你可以看到它捕獲關鍵事件(f.i.來實現功能,比如進入下一行的輸入按下)。作爲解決方案,我建議實現從DataGrid繼承自己的網格,並添加當用戶按下輸入(或其他)按鈕時引發的事件。自己的控制:
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();
}
}
我會公開幾步。所以讓我們開始吧..
1)在這個類的構造函數中聲明你的事件。
this.DataGrid1.KeyDown += new KeyEventHandler(DataGrid1_KeyDown);
you also can it in XAML file.
...KeyDown="DataGrid1_KeyDown".....
2)轉到您的keydown事件&線制的代碼。
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)現在由明白線的代碼線
ⅰ)前3行被用來取一個數據網格的哪一行被選中。
ii)在這種情況下,當新行添加時,我已經使用了Tab鍵,你也可以改變這個。另外一種情況是,如果用戶預置Tab + Shift,那麼它會通過(默認爲控制焦點)。
iii)然後檢查它是否是最後一行&該網格的最後一列,如果是,則添加新行或其他。
IV)來添加一個空白的新行只是通過你的對象(EDMX型號表)
以及弗拉基米爾,似乎是最後一行退出後添加新行沒有簡單/直接的方式。上述解決方案將起作用,但也會在其他重要新聞事件中引發事件的後果。 – 2011-04-04 08:56:19
yeap,我已經在 – 2011-04-04 09:06:34
以上的代碼中添加了按下的鍵的檢查,以及我不能將整個解決方案作爲註釋(註釋長度驗證)我已經把它作爲下面的答案。在'按鍵'檢查時,當我使用它時,我沒有在我的日誌中看到'Enter'鍵。 – 2011-04-04 09:13:44