This is a migrated thread and some comments may be shown as answers.

[Solved] Tabs and Row virtualization

2 Answers 164 Views
GridView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
david ocasio
Top achievements
Rank 1
david ocasio asked on 15 Oct 2009, 03:08 PM
Ive been trying to do something  a little not standard
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

Sort by
0
david ocasio
Top achievements
Rank 1
answered on 18 Oct 2009, 12:22 AM

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 ObjectByVal CellIndex As Integer)  
        Dim container As GridViewRow = ItemsControl.ItemsGenerator.ContainerFromItem(RowData)  
        BringDataItemIntoView(RowData)  
 
        Dim args() As Object = {RowData, CellIndex}  
        Dispatcher.BeginInvoke(New Action(Of ObjectInteger)(AddressOf SetFocus), args)  
    End Sub 
 
    Private Sub SetFocus(ByVal rowdataitem As ObjectByVal 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 ObjectByVal 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 ObjectByVal 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 ObjectByVal 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> 
 

0
Hristo
Telerik team
answered on 20 Oct 2009, 08:00 AM
Hi david ocasio,

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.
Tags
GridView
Asked by
david ocasio
Top achievements
Rank 1
Answers by
david ocasio
Top achievements
Rank 1
Hristo
Telerik team
Share this question
or