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

Group expanding at ramdom (bug?)

6 Answers 143 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Per
Top achievements
Rank 1
Per asked on 02 Feb 2011, 10:56 AM
Hi

I have a GridView with 3 column, Id, Name and Quantity
I have created a group using the Name column.
I have a GroupEvaluate that calculates the total quantity in a group and displays it on the group header.

My gridView is bound to a DataSource (AccountRowBindingSource) containing and Generic List of Linq2SQL objects (called RowsToAdd).
My first problem: When I add rows to my RowsToAdd the GroupSummaryEvaluate event is not fired so my group header is not recalculated.
However, If I expand the group, I can see all added rows.

To force the GroupEvaluate event to trigger I added a ResetBinding call, like this
AccountRowBindingSource.DataSource = RowsToAdd
AccountRowBindingSource.ResetBindings(False)

After the change, the GroupSummaryEvaluate event is fired and the correct summary is displayed in the header.
BUT..
Now Groups in the RadGrid randomly expands. I can see that its the ResetBindings that is making this happen.
So, Why is the groups expanding even though I have set the AutoExpandGroups = false?

Regards
Per



6 Answers, 1 is accepted

Sort by
0
Richard Slade
Top achievements
Rank 2
answered on 02 Feb 2011, 11:23 AM
Hello Per,

I'm trying to replicate your issue but I haven't been able to at the moment, though this may be because I haven't quite replicated what you are doing.
Firstly, can I ask what version of the controls you are using so I know we are both on the same? I am on the latest 2010 Q3 SP1 version.

I have prepared a small sample. Please could you give it a try in a new project, and alter anything that you need to in order to replicate your issue, and I'll be happy to try and help

Designer File

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form
  
    'Form overrides dispose to clean up the component list. 
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub
  
    'Required by the Windows Form Designer 
    Private components As System.ComponentModel.IContainer
  
    'NOTE: The following procedure is required by the Windows Form Designer 
    'It can be modified using the Windows Form Designer.   
    'Do not modify it using the code editor. 
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Dim SortDescriptor1 As Telerik.WinControls.Data.SortDescriptor = New Telerik.WinControls.Data.SortDescriptor()
        Me.RadGridView1 = New Telerik.WinControls.UI.RadGridView()
        CType(Me.RadGridView1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'RadGridView1
        '
        Me.RadGridView1.BackColor = System.Drawing.SystemColors.Control
        Me.RadGridView1.Cursor = System.Windows.Forms.Cursors.Default
        Me.RadGridView1.Dock = System.Windows.Forms.DockStyle.Fill
        Me.RadGridView1.Font = New System.Drawing.Font("Segoe UI", 8.25!)
        Me.RadGridView1.ForeColor = System.Drawing.SystemColors.ControlText
        Me.RadGridView1.ImeMode = System.Windows.Forms.ImeMode.NoControl
        Me.RadGridView1.Location = New System.Drawing.Point(0, 0)
        '
        'RadGridView1
        '
        Me.RadGridView1.MasterTemplate.EnableAlternatingRowColor = True
        Me.RadGridView1.MasterTemplate.ShowRowHeaderColumn = False
        SortDescriptor1.Direction = System.ComponentModel.ListSortDirection.Descending
        SortDescriptor1.PropertyName = "DateStamp"
        Me.RadGridView1.MasterTemplate.SortDescriptors.AddRange(New Telerik.WinControls.Data.SortDescriptor() {SortDescriptor1})
        Me.RadGridView1.Name = "RadGridView1"
        Me.RadGridView1.Padding = New System.Windows.Forms.Padding(0, 0, 0, 1)
        Me.RadGridView1.RightToLeft = System.Windows.Forms.RightToLeft.No
        '
        '
        '
        Me.RadGridView1.RootElement.Padding = New System.Windows.Forms.Padding(0, 0, 0, 1)
        Me.RadGridView1.Size = New System.Drawing.Size(874, 443)
        Me.RadGridView1.TabIndex = 0
        Me.RadGridView1.Text = "RadGridView1"
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(874, 443)
        Me.Controls.Add(Me.RadGridView1)
        Me.Name = "Form1"
        Me.Text = "Form 1"
        CType(Me.RadGridView1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)
  
    End Sub
    Friend WithEvents RadGridView1 As Telerik.WinControls.UI.RadGridView
  
End Class

Form1.vb
Imports Telerik.WinControls.UI
Imports System.Text
Imports System.ComponentModel
Imports Telerik.WinControls
Imports Telerik.WinControls.Data
  
Public Class Form1
  
    Private m_BindingSource As New BindingSource()
    Private m_List As New List(Of MyObject)
  
    Public Sub New()
        InitializeComponent()
  
        RadGridView1.AutoSizeRows = False
        RadGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
        RadGridView1.AutoGenerateColumns = True
        RadGridView1.AutoExpandGroups = False
  
        Populate()
        m_BindingSource.DataSource = m_List
        Me.RadGridView1.DataSource = m_BindingSource
  
        Dim descriptor As New GroupDescriptor()
        descriptor.GroupNames.Add("Name", ListSortDirection.Ascending)
        Me.RadGridView1.GroupDescriptors.Add(descriptor)
  
    End Sub
  
    Private Sub Populate()
        m_List.Clear()
        m_List.Add(New MyObject("Name 1", 10, 1))
        m_List.Add(New MyObject("Name 2", 15, 2))
        m_List.Add(New MyObject("Name 3", 20, 3))
        m_List.Add(New MyObject("Name 4", 25, 4))
    End Sub
  
  
    Private Sub RadGridView1_GroupSummaryEvaluate(ByVal sender As System.Object, ByVal e As Telerik.WinControls.UI.GroupSummaryEvaluationEventArgs) Handles RadGridView1.GroupSummaryEvaluate
        If e.SummaryItem.Name = "Name" Then
            Dim nameCount As Integer = e.Group.ItemCount
            e.FormatString = [String].Format("For {1} there are {0} rows", nameCount, e.Value)
        End If
    End Sub
End Class
  
Public Class MyObject
  
    Public Sub New()
    End Sub
  
    Public Sub New(ByVal name As String, ByVal quantity As Integer, ByVal id As Integer)
        Me.Name = name
        Me.Quantity = quantity
        Me.Id = id
    End Sub
  
    Public Property Name As String
    Public Property Quantity As Integer
    Public Property Id As Integer
End Class

Regards,
Richard
0
Per
Top achievements
Rank 1
answered on 02 Feb 2011, 04:29 PM
Hi and thanks for your quick reply :)
I was able to reproduce this behavior and have attached the code below.
After you started the program, press the column header "Column1" two time so its sorted.
Then press Button1

The grid will now expand one of the groups without reason.

Designer File
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
  Inherits System.Windows.Forms.Form
  
  'Form overrides dispose to clean up the component list.  
  <System.Diagnostics.DebuggerNonUserCode()> _
  Protected Overrides Sub Dispose(ByVal disposing As Boolean)
    Try
      If disposing AndAlso components IsNot Nothing Then
        components.Dispose()
      End If
    Finally
      MyBase.Dispose(disposing)
    End Try
  End Sub
  
  'Required by the Windows Form Designer  
  Private components As System.ComponentModel.IContainer
  
  'NOTE: The following procedure is required by the Windows Form Designer  
  'It can be modified using the Windows Form Designer.    
  'Do not modify it using the code editor.  
  <System.Diagnostics.DebuggerStepThrough()> _
  Private Sub InitializeComponent()
    Dim GridViewTextBoxColumn1 As Telerik.WinControls.UI.GridViewTextBoxColumn = New Telerik.WinControls.UI.GridViewTextBoxColumn()
    Dim GridViewTextBoxColumn2 As Telerik.WinControls.UI.GridViewTextBoxColumn = New Telerik.WinControls.UI.GridViewTextBoxColumn()
    Dim GridViewTextBoxColumn3 As Telerik.WinControls.UI.GridViewTextBoxColumn = New Telerik.WinControls.UI.GridViewTextBoxColumn()
    Me.RadGridView1 = New Telerik.WinControls.UI.RadGridView()
    Me.Button1 = New System.Windows.Forms.Button()
    CType(Me.RadGridView1, System.ComponentModel.ISupportInitialize).BeginInit()
    CType(Me.RadGridView1.MasterTemplate, System.ComponentModel.ISupportInitialize).BeginInit()
    Me.SuspendLayout()
    '
    'RadGridView1
    '
    Me.RadGridView1.BackColor = System.Drawing.SystemColors.Control
    Me.RadGridView1.Cursor = System.Windows.Forms.Cursors.Default
    Me.RadGridView1.Font = New System.Drawing.Font("Segoe UI", 8.25!)
    Me.RadGridView1.ForeColor = System.Drawing.SystemColors.ControlText
    Me.RadGridView1.ImeMode = System.Windows.Forms.ImeMode.NoControl
    Me.RadGridView1.Location = New System.Drawing.Point(12, 190)
    '
    'RadGridView1
    '
    Me.RadGridView1.MasterTemplate.AllowAddNewRow = False
    Me.RadGridView1.MasterTemplate.AllowDeleteRow = False
    Me.RadGridView1.MasterTemplate.AllowEditRow = False
    Me.RadGridView1.MasterTemplate.AutoGenerateColumns = False
    Me.RadGridView1.MasterTemplate.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill
    GridViewTextBoxColumn1.FieldName = "Id"
    GridViewTextBoxColumn1.HeaderText = "column1"
    GridViewTextBoxColumn1.Name = "id"
    GridViewTextBoxColumn1.Width = 292
    GridViewTextBoxColumn2.FieldName = "name"
    GridViewTextBoxColumn2.HeaderText = "column1"
    GridViewTextBoxColumn2.Name = "name"
    GridViewTextBoxColumn2.Width = 292
    GridViewTextBoxColumn3.FieldName = "quantity"
    GridViewTextBoxColumn3.HeaderText = "column1"
    GridViewTextBoxColumn3.Name = "quantity"
    GridViewTextBoxColumn3.Width = 290
    Me.RadGridView1.MasterTemplate.Columns.AddRange(New Telerik.WinControls.UI.GridViewDataColumn() {GridViewTextBoxColumn1, GridViewTextBoxColumn2, GridViewTextBoxColumn3})
    Me.RadGridView1.MasterTemplate.EnableAlternatingRowColor = True
    Me.RadGridView1.MasterTemplate.ShowRowHeaderColumn = False
    Me.RadGridView1.Name = "RadGridView1"
    Me.RadGridView1.Padding = New System.Windows.Forms.Padding(0, 0, 0, 1)
    Me.RadGridView1.RightToLeft = System.Windows.Forms.RightToLeft.No
    '
    '
    '
    Me.RadGridView1.RootElement.Padding = New System.Windows.Forms.Padding(0, 0, 0, 1)
    Me.RadGridView1.ShowGroupPanel = False
    Me.RadGridView1.Size = New System.Drawing.Size(874, 443)
    Me.RadGridView1.TabIndex = 0
    Me.RadGridView1.Text = "RadGridView1"
    '
    'Button1
    '
    Me.Button1.Location = New System.Drawing.Point(184, 52)
    Me.Button1.Name = "Button1"
    Me.Button1.Size = New System.Drawing.Size(75, 23)
    Me.Button1.TabIndex = 1
    Me.Button1.Text = "Button1"
    Me.Button1.UseVisualStyleBackColor = True
    '
    'Form1
    '
    Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
    Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
    Me.ClientSize = New System.Drawing.Size(915, 645)
    Me.Controls.Add(Me.Button1)
    Me.Controls.Add(Me.RadGridView1)
    Me.Name = "Form1"
    Me.Text = "Form 1"
    CType(Me.RadGridView1.MasterTemplate, System.ComponentModel.ISupportInitialize).EndInit()
    CType(Me.RadGridView1, System.ComponentModel.ISupportInitialize).EndInit()
    Me.ResumeLayout(False)
  
  End Sub
  Friend WithEvents RadGridView1 As Telerik.WinControls.UI.RadGridView
  Friend WithEvents Button1 As System.Windows.Forms.Button
  
End Class

Form1.vb
Imports Telerik.WinControls.UI
Imports System.Text
Imports System.ComponentModel
Imports Telerik.WinControls
Imports Telerik.WinControls.Data
  
Public Class Form1
  
  Private m_BindingSource As New BindingSource()
  Private m_List As New List(Of MyObject)
  
  Public Sub New()
    InitializeComponent()
  
    RadGridView1.AutoSizeRows = False
    RadGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
    RadGridView1.AutoGenerateColumns = True
    RadGridView1.AutoExpandGroups = False
  
    Populate()
    m_BindingSource.RaiseListChangedEvents = True
    m_BindingSource.DataSource = m_List
    Me.RadGridView1.DataSource = m_BindingSource
  
    Dim descriptor As New GroupDescriptor()
    descriptor.GroupNames.Add("Name", ListSortDirection.Ascending)
    Me.RadGridView1.GroupDescriptors.Add(descriptor)
  
  End Sub
  
  Private Sub Populate()
    m_List.Clear()
    m_List.Add(New MyObject("Name 1", 10, 1))
    m_List.Add(New MyObject("Name 2", 15, 2))
    m_List.Add(New MyObject("Name 3", 20, 3))
    m_List.Add(New MyObject("Name 4", 25, 4))
  End Sub
  
  Private Sub RadGridView1_RowsChanging(ByVal sender As Object, ByVal e As Telerik.WinControls.UI.GridViewCollectionChangingEventArgs) Handles RadGridView1.RowsChanging
    Select Case e.Action
      Case Telerik.WinControls.Data.NotifyCollectionChangedAction.Remove
      Case Telerik.WinControls.Data.NotifyCollectionChangedAction.Add
        'For Each RowToAdd As Telerik.WinControls.UI.GridViewDataRowInfo In e.NewItems
        '  Dim AccountRow As DataAccessLayer.AccountRow = CType(RowToAdd.DataBoundItem, DataAccessLayer.AccountRow)
        '  Dim Product As DataAccessLayer.Product = BusinessLogic.Product.LoadProduct(AccountRow.ProductId)
  
        '  RowToAdd.Cells("ProductName").Value = Product.SortOrder.ToString.PadLeft(3, "0"c) & " " & RowToAdd.Cells("ProductName").Value.ToString
        'Next
    End Select
  End Sub
  
  Private Sub RadGridView1_GroupSummaryEvaluate(ByVal sender As System.Object, ByVal e As Telerik.WinControls.UI.GroupSummaryEvaluationEventArgs) Handles RadGridView1.GroupSummaryEvaluate
    If e.SummaryItem.Name = "Name" Then
      Dim itemCount As Integer
      For i As Integer = 1 To e.Group.ItemCount
        Dim Row As Telerik.WinControls.UI.GridViewRowInfo = e.Group.Item(i - 1)
        itemCount += CInt(Row.Cells("Quantity").Value)
      Next
      e.FormatString = [String].Format("{0} ({1} st)", e.Value, itemCount.ToString)
    End If
  End Sub
  
  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    m_List.Add(New MyObject("Name 5", 30, 5))
    'Update added rows
    m_BindingSource.DataSource = m_List
    m_BindingSource.ResetBindings(False)
  End Sub
End Class
  
Public Class MyObject
  
  Public Sub New()
  End Sub
  
  Public Sub New(ByVal name As String, ByVal quantity As Integer, ByVal id As Integer)
    Me.Name = name
    Me.Quantity = quantity
    Me.Id = id
  End Sub
  
  Public Property Name As String
  Public Property Quantity As Integer
  Public Property Id As Integer
End Class

Regards
Per
0
Accepted
Richard Slade
Top achievements
Rank 2
answered on 02 Feb 2011, 04:50 PM
Hello Per,

To be honest, I am not sure why it is expanding. However, I can offer a workaround which should work for you.
Please can you try amending your sample as follows

Private m_CanExpand As Boolean = True
Private Sub RadGridView_GroupExpanding(ByVal sender As Object, ByVal e As CancelEventArgs)
    e.Cancel = Not m_CanExpand
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    m_CanExpand = False
    Using Me.RadGridView1.DeferRefresh()
        AddHandler RadGridView1.GroupExpanding, AddressOf RadGridView_GroupExpanding
        m_List.Add(New MyObject("Name 5", 30, 5))
        'Update added rows 
        m_BindingSource.DataSource = m_List
        m_BindingSource.ResetBindings(False)
    End Using
    m_CanExpand = True
End Sub

Hope that helps
Richard
0
Per
Top achievements
Rank 1
answered on 02 Feb 2011, 05:03 PM
Hi

I implemented a similar solution today to cancel the expand event if its not the user doing it.
This must be some kind of "sorting" bug, because it does not occure if you havnt sorted the grid.

Probly something to do with the grid trying to maintain the open group even if the user resorts the columns.

Thanks again for the help :)

Regards
Per
0
Richard Slade
Top achievements
Rank 2
answered on 02 Feb 2011, 05:06 PM
Hi Per,

I'm glad that helped and you have a suitable workaround. I'll see if I can find out any more on it, and let you know if I do.
All the best
Richard
0
Julian Benkov
Telerik team
answered on 07 Feb 2011, 12:28 PM
Hi Per,

Another possible solution is to use the BindingList<> generic list that supports notifications, hence RadGridView control will update itself automatically:

Imports Telerik.WinControls.UI
Imports System.Text
Imports System.ComponentModel
Imports Telerik.WinControls
Imports Telerik.WinControls.Data
   
Public Class Form1
   
  Private m_BindingSource As New BindingSource()
  Private m_List As New BindingList(Of MyObject)
   
  Public Sub New()
    InitializeComponent()
   
    RadGridView1.AutoSizeRows = False
    RadGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
    RadGridView1.AutoGenerateColumns = True
    RadGridView1.AutoExpandGroups = False
   
    Populate()
    m_BindingSource.RaiseListChangedEvents = True
    m_BindingSource.DataSource = m_List
    Me.RadGridView1.DataSource = m_BindingSource
   
    Dim descriptor As New GroupDescriptor()
    descriptor.GroupNames.Add("Name", ListSortDirection.Ascending)
    Me.RadGridView1.GroupDescriptors.Add(descriptor)
   
  End Sub
   
  Private Sub Populate()
    m_List.Clear()
    m_List.Add(New MyObject("Name 1", 10, 1))
    m_List.Add(New MyObject("Name 2", 15, 2))
    m_List.Add(New MyObject("Name 3", 20, 3))
    m_List.Add(New MyObject("Name 4", 25, 4))
  End Sub
   
  Private Sub RadGridView1_RowsChanging(ByVal sender As Object, ByVal e As Telerik.WinControls.UI.GridViewCollectionChangingEventArgs) Handles RadGridView1.RowsChanging
    Select Case e.Action
      Case Telerik.WinControls.Data.NotifyCollectionChangedAction.Remove
      Case Telerik.WinControls.Data.NotifyCollectionChangedAction.Add
        'For Each RowToAdd As Telerik.WinControls.UI.GridViewDataRowInfo In e.NewItems
        '  Dim AccountRow As DataAccessLayer.AccountRow = CType(RowToAdd.DataBoundItem, DataAccessLayer.AccountRow)
        '  Dim Product As DataAccessLayer.Product = BusinessLogic.Product.LoadProduct(AccountRow.ProductId)
   
        '  RowToAdd.Cells("ProductName").Value = Product.SortOrder.ToString.PadLeft(3, "0"c) & " " & RowToAdd.Cells("ProductName").Value.ToString
        'Next
    End Select
  End Sub
   
  Private Sub RadGridView1_GroupSummaryEvaluate(ByVal sender As System.Object, ByVal e As Telerik.WinControls.UI.GroupSummaryEvaluationEventArgs) Handles RadGridView1.GroupSummaryEvaluate
    If e.SummaryItem.Name = "Name" Then
      Dim itemCount As Integer
      For i As Integer = 1 To e.Group.ItemCount
        Dim Row As Telerik.WinControls.UI.GridViewRowInfo = e.Group.Item(i - 1)
        itemCount += CInt(Row.Cells("Quantity").Value)
      Next
      e.FormatString = [String].Format("{0} ({1} st)", e.Value, itemCount.ToString)
    End If
  End Sub
   
  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    m_List.Add(New MyObject("Name 5", 30, 5))
    'Me.RadGridView1.MasterTemplate.Refresh() 'can be used for additional update
   
  End Sub
End Class
   
Public Class MyObject
   
  Public Sub New()
  End Sub
   
  Public Sub New(ByVal name As String, ByVal quantity As Integer, ByVal id As Integer)
    Me.Name = name
    Me.Quantity = quantity
    Me.Id = id
  End Sub
   
  Public Property Name As String
  Public Property Quantity As Integer
  Public Property Id As Integer
End Class

I hope this will help.

Best wishes,
Julian Benkov
the Telerik team
Q3’10 SP1 of RadControls for WinForms is available for download; also available is the Q1'11 Roadmap for Telerik Windows Forms controls.
Tags
GridView
Asked by
Per
Top achievements
Rank 1
Answers by
Richard Slade
Top achievements
Rank 2
Per
Top achievements
Rank 1
Julian Benkov
Telerik team
Share this question
or