Scrolling grid view with custom column and cells visualy "shuffles" data.

1 Answer 54 Views
DropDownList GridView TextBox
Oliver
Top achievements
Rank 1
Oliver asked on 15 Jan 2024, 12:12 PM

Hello,

I created a custom column and cell in my grid following the progress-bar example

https://docs.telerik.com/devtools/winforms/controls/gridview/cells/creating-custom-cells

But I have modified it so that I can view either a textBoxElement or a dropDownListElement depending on what data is in the cell. It all seems to work just fine until I scroll the grid. Scrolling visualy shuffles the data in the custom column. I've tried to take the cell-formatting route but without success. Is it possible to achieve this result somehow?

 Public Class GridParameterValueElement
        Inherits GridDataCellElement

        Public Sub New(ByVal column As GridViewColumn, ByVal row As GridRowElement)
            MyBase.New(column, row)
        End Sub

        Private isInitialized As Boolean
        Private firstTimeIndexChanged As Boolean = True
        Private dropDown As RadDropDownListElement
        Private textBox As RadTextBoxElement
        Protected Overrides Sub CreateChildElements()
            MyBase.CreateChildElements()
            dropDown = New RadDropDownListElement() With { 
                .DropDownStyle = Telerik.WinControls.RadDropDownStyle.DropDownList
            }
            textBox = New RadTextBoxElement() With {
                .Enabled = True,
                .ClickMode = Telerik.WinControls.ClickMode.Press,
                .ZIndex = -1
            }
            If Me.Children.Contains(dropDown) Then Me.Children.Remove(dropDown)
            If Me.Children.Contains(textBox) Then Me.Children.Remove(textBox)
            Me.Children.Add(dropDown)
            Me.Children.Add(textBox)
            AddHandler dropDown.SelectedIndexChanged, AddressOf SelectedIndexChanged
            AddHandler textBox.TextChanged, AddressOf TextInBoxChanged
            'AddHandler textBox.Click, AddressOf TextBox_Click

        End Sub

        Protected Overrides Sub DisposeManagedResources()
            RemoveHandler dropDown.SelectedIndexChanged, AddressOf SelectedIndexChanged
            RemoveHandler textBox.TextChanged, AddressOf TextInBoxChanged
            MyBase.DisposeManagedResources()
        End Sub
            
        'Private Sub TextBox_Click(sender As Object, e As EventArgs)
        '    Dim test  = sender
        'End Sub


        Public Overrides Sub SetContent()
            MyBase.SetContent()

            If Me.RowInfo.Cells("DisplayValue").Tag IsNot Nothing Then

                If Not Me.isInitialized Then 
                    If Me.Children.Contains(textBox) Then Me.Children.Remove(textBox)

                    With Me.dropDown
                        .DataSource = Me.RowInfo.Cells("DisplayValue").Tag
                        .ValueMember = ("DevelopmentTypeParameterValueId")
                        .DisplayMember = ("ParameterValue")
                    End With 
                End If

                If Me.RowInfo.Tag IsNot Nothing Then
                    RemoveHandler dropDown.SelectedIndexChanged, AddressOf SelectedIndexChanged
                    dropDown.SelectedIndex = DirectCast(Me.RowInfo.Tag, Integer)
                    AddHandler dropDown.SelectedIndexChanged, AddressOf SelectedIndexChanged
                Else
                    RemoveHandler dropDown.SelectedIndexChanged, AddressOf SelectedIndexChanged
                    dropDown.SelectedIndex = -1
                    AddHandler dropDown.SelectedIndexChanged, AddressOf SelectedIndexChanged
                End If

            ElseIf Me.Value IsNot Nothing AndAlso Me.Value IsNot DBNull.Value Then

                If Not Me.isInitialized Then 
                    If Me.Children.Contains(dropDown) Then Me.Children.Remove(dropDown)
                    Me.textBox.Text = CStr(Me.Value)
                End If
       
            End If

            Me.isInitialized = True
        
        End Sub


        Protected Overrides ReadOnly Property ThemeEffectiveType() As Type
            Get
                Return GetType(GridDataCellElement)
            End Get
        End Property

        Public Overrides Function IsCompatible(ByVal data As GridViewColumn, ByVal context As Object) As Boolean
            Return TypeOf data Is GridViewParameterValueColumn AndAlso TypeOf context Is GridDataRowElement
        End Function

    End Class
    
    Public Class GridViewParameterValueColumn
        Inherits GridViewDataColumn
        Public Sub New(ByVal fieldName As String)
            MyBase.New(fieldName)
        End Sub
        Public Overrides Function GetCellType(ByVal row As GridViewRowInfo) As Type
            If TypeOf row Is GridViewDataRowInfo Then
                Return GetType(GridParameterValueElement)
            End If
            Return MyBase.GetCellType(row)
        End Function
    End Class


1 Answer, 1 is accepted

Sort by
0
Nadya | Tech Support Engineer
Telerik team
answered on 16 Jan 2024, 11:02 AM

Hello, Oliver,

It is important to note that RadGridView uses UI virtualization. This means that cell elements are created for the currently visible cells and they are being reused during operations like scrolling, filtering, etc. The IsCompatible method of the GridDataCellElement allows you to control for which columns exactly this cell is appropriate. So that you can restrict in which columns to be reused. However, the default cell element is compatible with all columns. You can create a custom GridDataCellElement and override its IsCompatible method which should return true for all the columns except the custom one. Thus, the default cell element wouldn't be reused in the custom column. Please refer to the following KB article that demonstrates a similar approach: How to Create Custom Cells with Input Elements - Telerik UI for WinForms 

I have noticed that you remove, then add RadDropDownListElement or RadTextBoxElement. If you need to show one of them (not both element) in a specific cell, you can consider to add both of them and show just one element and hide the other upon some condition by setting the Visibility property.

In case you are having further difficulties, it would be greatly appreciated if you could provide a sample runnable project demonstrating the exact setup that you have so we can test the precise case. Thank you for your cooperation.

I hope this information helps. If you need any further assistance, please don't hesitate to contact me. 

Regards,
Nadya | Tech Support Engineer
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Tags
DropDownList GridView TextBox
Asked by
Oliver
Top achievements
Rank 1
Answers by
Nadya | Tech Support Engineer
Telerik team
Share this question
or