and i may have come to the conclution that i can't do it
with your gridview control
So i will throw it out to you
I have a grid where i have placed an exposed textbox
(i.e. in celltemplate not edittemplate) that shows up of course for every row
This grid is to be used as a worksheet (allowing entry on any row).
<telerikGridView:GridViewDataColumn HeaderText="Qty to Move" Width="Auto" TextAlignment="Center" >
<telerikGridView:GridViewDataColumn.CellTemplate>
<DataTemplate >
<TextBox Text="{Binding QtyOnHand,Mode=TwoWay}" TextAlignment="Right" x:Name="QQ2" Tag="tabstop" />
</DataTemplate>
</telerikGridView:GridViewDataColumn.CellTemplate>
</telerikGridView:GridViewDataColumn>
My problem is that "Keyboard Tabing" between the textboxes does not work .
Instead "Keyboard Tabing" goes to the cells of the grid which is not what i want.
My thought was to intercept the keydown event and set focus to the next textbox manually.
With your prior help i have been able to find the previous and next control to pass focus to .But when i started to search for ways fo find the next "row" index to search for controls to focus on.
It occured to me that since you are doing row virtualiztion that row may not even exist yet.
<<< so the questions >>>
- Am i doing this Halfass Backwards ??
- Is there a better way to do it ??
- If what i am doing is viable how then can i find the next or previous sibling row so i can move focus from currently focused controls
to controls on that previous or next row. ?? - I suppose if i am on the top row i could try and scroll the next row into view effectivly loading it and then try and focus
but that sure sounds funky . Or is that how to do it ??
Any and all help will be apprieciated guys.
Feel free to say i am crazy for trying to do this.
thanks
dco
2 Answers, 1 is accepted
Using prior posts and a lot of trial and error
I found the answers necessary to make my worksheet.
The worksheet has exposed textboxes (or other controls if necssary).
The textboxes are always available for editing.
Navigation between the open controls is accomplished
Using
- tabs
- enter key
- home key
- end key
Row virtualization is taken into account and the home and end key combinations bring you to the first and last row respecivily.
Textboxes need to be added using cell templates and not edit templates since edit mode is never entered and is shut off.
Sure Hope im not duplicating existing functionality or pending devlopment.
Either way, Hope this helps the next guy.
dco
| Imports System.Windows.Data |
| Imports System.Windows.Ria.Data |
| Imports Telerik.Windows.Controls |
| Imports System.ComponentModel |
| Imports System.ComponentModel.DataAnnotations |
| Imports System.Collections.ObjectModel |
| Imports System.Windows.Automation |
| Public Class agWorkSheet |
| Inherits Telerik.Windows.Controls.RadGridView |
| ' this is a worksheet with open textboxes,checkboxes, and dropdowns |
| ' celltemplates need to be added in the xaml exposing the controls ... istabstop = true for those you wanted included in the navigation |
| ' editmode will never be entered |
| ' we are going to capture tabs,enter and up/down arrow keys ... and take care of the navigation ourselves |
| Public Shadows ReadOnly Property IsReadonly() |
| Get |
| Return MyBase.IsReadOnly |
| End Get |
| End Property |
| Public Sub New() |
| MyBase.New() |
| MyBase.IsReadOnly = True |
| AutoGenerateColumns = False |
| IsFilteringAllowed = False |
| ShowColumnFooters = False |
| ShowGroupPanel = False |
| IsTabStop = False |
| SelectionMode = Controls.SelectionMode.Single |
| End Sub |
| ' so where am i |
| Protected Function getRow(ByVal control As Control) As GridViewRow |
| Return control.ParentOfType(Of GridViewRow)() |
| End Function |
| Protected Function getCell(ByVal control As Control) As GridViewCell |
| Return control.ParentOfType(Of GridViewCell)() |
| End Function |
| Protected Function getCellIndex(ByVal control As Control) As Integer |
| Return getRow(control).Cells.IndexOf(getCell(control)) |
| End Function |
| ' got to keep trucking |
| Protected Sub MoveRight(ByVal control As Control) |
| Dim ParentRow As GridViewRow = getRow(control) |
| Dim ParentCellIndex As Integer = getCellIndex(control) |
| Dim NextCTL = _ |
| From ctl In getRowControls(ParentRow) _ |
| Where getCellIndex(ctl) > ParentCellIndex _ |
| Select ctl Order By getCellIndex(ctl) Ascending |
| If IsNothing(NextCTL) OrElse NextCTL.Count = 0 Then |
| ' no controls left on this line |
| MoveDown(control, True) |
| Else |
| NextCTL.First.Focus() |
| End If |
| End Sub |
| Protected Sub MoveLeft(ByVal control As Control) |
| Dim ParentRow As GridViewRow = getRow(control) |
| Dim ParentCellIndex As Integer = getCellIndex(control) |
| Dim NextCTL = _ |
| From ctl In getRowControls(ParentRow) _ |
| Where getCellIndex(ctl) < ParentCellIndex _ |
| Select ctl Order By getCellIndex(ctl) Descending |
| If IsNothing(NextCTL) OrElse NextCTL.Count = 0 Then |
| ' no controls left on this line |
| MoveUp(control, True) |
| Else |
| NextCTL.First.Focus() |
| End If |
| End Sub |
| Protected Sub MoveUp(ByVal control As Control, ByVal FlagWrap As Boolean) |
| Dim ParentRow As GridViewRow = getRow(control) |
| Dim RowIndex As Integer = Items.IndexOf(ParentRow.DataContext) |
| Dim NextItem As Object = Nothing |
| If RowIndex > 0 Then |
| NextItem = Items.Cast(Of Object).Skip(RowIndex - 1).FirstOrDefault |
| End If |
| If IsNothing(NextItem) = False Then |
| Dim CellIndex As Integer = 0 |
| If FlagWrap Then |
| CellIndex = getCellIndex(getRowControls(ParentRow).OrderByDescending(Function(ctl) getCellIndex(ctl)).First()) ' get first cell with a control in it |
| Else |
| CellIndex = getCellIndex(control) |
| End If |
| MoveToItem(NextItem, CellIndex) |
| Else |
| MoveToLast(control, FlagWrap) |
| End If |
| End Sub |
| Protected Sub MoveDown(ByVal control As Control, ByVal FlagWrap As Boolean) |
| Dim ParentRow As GridViewRow = getRow(control) |
| Dim RowIndex As Integer = Items.IndexOf(ParentRow.DataContext) |
| Dim NextItem As Object = Items.Cast(Of Object).Skip(RowIndex + 1).FirstOrDefault |
| If IsNothing(NextItem) = False Then |
| Dim CellIndex As Integer = 0 |
| If FlagWrap Then |
| CellIndex = getCellIndex(getRowControls(ParentRow).OrderBy(Function(ctl) getCellIndex(ctl)).First()) ' get first cell with a control in it |
| Else |
| CellIndex = getCellIndex(control) |
| End If |
| MoveToItem(NextItem, CellIndex) |
| Else |
| MoveToFirst(control, FlagWrap) |
| End If |
| End Sub |
| Protected Sub MoveToLast(ByVal control As Control, ByVal FlagWrap As Boolean) |
| Dim ParentRow As GridViewRow = getRow(control) |
| Dim RowIndex As Integer = Items.IndexOf(ParentRow.DataContext) |
| Dim CellIndex As Integer = 0 |
| If FlagWrap Then |
| CellIndex = getCellIndex(getRowControls(ParentRow).OrderByDescending(Function(ctl) getCellIndex(ctl)).First()) ' get last cell with a control in it |
| Else |
| CellIndex = getCellIndex(control) |
| End If |
| Dim lastItem As Object = Items(Items.Count - 1) |
| MoveToItem(lastItem, CellIndex) |
| End Sub |
| Protected Sub MoveToFirst(ByVal control As Control, ByVal FlagWrap As Boolean) |
| Dim ParentRow As GridViewRow = getRow(control) |
| Dim RowIndex As Integer = Items.IndexOf(ParentRow.DataContext) |
| Dim CellIndex As Integer = 0 |
| If FlagWrap Then |
| CellIndex = getCellIndex(getRowControls(ParentRow).OrderBy(Function(ctl) getCellIndex(ctl)).First()) ' get first cell with a control in it |
| Else |
| CellIndex = getCellIndex(control) |
| End If |
| Dim FirstItem As Object = Items(0) |
| MoveToItem(FirstItem, CellIndex) |
| End Sub |
| Protected Sub MoveToItem(ByVal RowData As Object, ByVal CellIndex As Integer) |
| Dim container As GridViewRow = ItemsControl.ItemsGenerator.ContainerFromItem(RowData) |
| BringDataItemIntoView(RowData) |
| Dim args() As Object = {RowData, CellIndex} |
| Dispatcher.BeginInvoke(New Action(Of Object, Integer)(AddressOf SetFocus), args) |
| End Sub |
| Private Sub SetFocus(ByVal rowdataitem As Object, ByVal cellindex As Integer) |
| Try |
| Dim FocusRow As GridViewRow = ItemsControl.ItemsGenerator.ContainerFromItem(rowdataitem) |
| Dim Control As Control = getRowControls(FocusRow).Where(Function(ctl) getCellIndex(ctl).Equals(cellindex)).First |
| Control.Focus() |
| Catch ex As Exception |
| ' happens occationaly ... not sure why ... maybe race... not so important to stop the entering |
| #If DEBUG Then |
| Throw ex |
| #End If |
| End Try |
| End Sub |
| Protected Sub Field_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Input.KeyEventArgs) |
| ' rewrite action for navigation keys |
| Dim control As Control = CType(sender, Control) |
| e.Handled = True |
| Select Case True |
| Case e.Key = Key.Tab |
| If Keyboard.Modifiers = ModifierKeys.Shift Then |
| MoveLeft(control) |
| Else |
| MoveRight(control) |
| End If |
| Case e.Key = Key.Enter |
| MoveRight(control) |
| Case e.Key = Key.Up |
| MoveUp(control, False) |
| Case e.Key = Key.Down |
| MoveDown(control, False) |
| Case e.Key = Key.Home |
| If Keyboard.Modifiers = ModifierKeys.Shift OrElse Keyboard.Modifiers = ModifierKeys.Control Then |
| MoveToFirst(control, True) |
| Else |
| MoveToFirst(control, False) |
| End If |
| Case e.Key = Key.End |
| If Keyboard.Modifiers = ModifierKeys.Shift OrElse Keyboard.Modifiers = ModifierKeys.Control Then |
| MoveToLast(control, True) |
| Else |
| MoveToLast(control, False) |
| End If |
| Case e.Key = Key.Right |
| MoveRight(control) |
| Case e.Key = Key.Left |
| MoveLeft(control) |
| Case Else |
| e.Handled = False |
| End Select |
| End Sub |
| Protected Sub Field_gotfocus(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) |
| Select Case True |
| Case TypeOf sender Is TextBox |
| Dim tb As TextBox = CType(sender, TextBox) |
| tb.SelectAll() |
| End Select |
| End Sub |
| Protected Overridable Function getRowControls(ByVal row As GridViewRow) As System.Collections.Generic.IEnumerable(Of Control) |
| ' narrowed types of controls so i didnt get "cells" and such in the list |
| ' tabstop must be true |
| Return row.ChildrenOfType(Of Control).Where(Function(CTL) (TypeOf CTL Is TextBox OrElse TypeOf CTL Is RadComboBox) AndAlso CTL.IsTabStop = True) |
| End Function |
| Protected Sub agWorkSheet2_RowLoaded(ByVal sender As Object, ByVal e As Telerik.Windows.Controls.GridView.RowLoadedEventArgs) Handles Me.RowLoaded |
| If TypeOf e.Row Is GridViewRow Then |
| Dim controls = getRowControls(e.Row) |
| For Each ctl As Control In controls |
| Select Case True |
| Case TypeOf ctl Is TextBox |
| AddHandler ctl.KeyDown, AddressOf Field_KeyDown |
| AddHandler ctl.GotFocus, AddressOf Field_gotfocus |
| Case Else |
| End Select |
| Next |
| End If |
| End Sub |
| End Class |
| <z:agWorkSheet Grid.Row="1" x:Name="StockGroupGrid" > |
| <telerikGridView:RadGridView.Columns> |
| <telerikGridView:GridViewDataColumn HeaderText="Bin Name" DataMemberPath="NameParentLoc" DataMemberBinding="{Binding NameParentLoc, Mode=TwoWay}" Width="Auto" /> |
| <telerikGridView:GridViewDataColumn IsReadOnly="True" HeaderText="Manufacturer Name" DataMemberBinding="{Binding NameManf, Mode=TwoWay}" Width="Auto" /> |
| <telerikGridView:GridViewDataColumn HeaderText="Part Number" DataMemberBinding="{Binding manfno, Mode=TwoWay}" Width="Auto" /> |
| <telerikGridView:GridViewDataColumn HeaderText="Qty On Hand" DataMemberBinding="{Binding QtyOnHand, Mode=TwoWay}" Width="Auto" TextAlignment="Right" > |
| <telerikGridView:GridViewDataColumn.CellTemplate> |
| <DataTemplate> |
| <TextBox Text="{Binding QtyOnHand,Mode=TwoWay}" IsTabStop="True" /> |
| </DataTemplate> |
| </telerikGridView:GridViewDataColumn.CellTemplate> |
| </telerikGridView:GridViewDataColumn> |
| <telerikGridView:GridViewDataColumn HeaderText="Qty To Move" DataMemberBinding="{Binding QtyToMove, Mode=TwoWay}" Width="Auto" TextAlignment="Right" > |
| <telerikGridView:GridViewDataColumn.CellTemplate> |
| <DataTemplate> |
| <TextBox Text="{Binding QtyToMove,Mode=TwoWay}" IsTabStop="True" /> |
| </DataTemplate> |
| </telerikGridView:GridViewDataColumn.CellTemplate> |
| </telerikGridView:GridViewDataColumn> |
| </telerikGridView:RadGridView.Columns> |
| </z:agWorkSheet> |
Let us know if you have other problems.
Greetings,
Hristo
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.