C1DataGrid performance problem in test application

Posted by: massong2 on 19 September 2017, 10:28 am EST

  • Posted 19 September 2017, 10:28 am EST

    Hi all,

    I’ve created a very simple test application to get familiar with the C1DataGrid for WPF, and I’m experiencing extreme performance problems. The application does nothing special: I started with only 3 columns and 100 rows.

    When I maximize the window it takes more than one second to redraw the window! It seems to me, that it has something to do with the re-layout of the columns. 10.000 rows make no difference, but 6 columns instead of 3 double the delay.

    What can I do to improve performance?

    Please see in the attached screenshot, how the effect looks like.

    This is my xaml:

    [xml]

    <Grid>
        <my:C1DataGrid HorizontalAlignment="Stretch" Name="C1DataGrid1" VerticalAlignment="Stretch" />
    </Grid>
    
    [/xml]

    This is the code behind:

    [vb]

    Class MainWindow

    ''' <summary>
    ''' Item with random values
    ''' </summary>
    ''' <remarks></remarks>
    Public Class RandomItem
        Public Property Number As Integer = CInt(Rnd() * 1000)
        Public Property Text As String = "Text " & CStr(CInt(Rnd() * 1000))
        Public Property [Boolean] As Boolean = CBool(CInt(Rnd()))
    End Class
    
    ''' <summary>
    ''' Constructor
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()
        MyBase.New()
    
        ' This call is required by the designer.
        InitializeComponent()
    
        ' Add any initialization after the InitializeComponent() call.
        Dim list As New List(Of RandomItem)
    
        For i As Integer = 1 To 100
            list.Add(New RandomItem)
        Next
    
        C1DataGrid1.ItemsSource = list
    End Sub
    

    End Class

    [/vb]

    Thanks for help,

    Christian

  • Posted 19 September 2017, 10:28 am EST

    What you see happen just the first time, right?

  • Posted 19 September 2017, 10:28 am EST

    Hi Leo,

    Thank you very much for your reply. No, it happens every time I maximize the window. It is true, that the rendering is a little bit faster at the 2nd time, but the black window background and the half rendered grid are still noticeable for a fraction of a second.

    I wanted to migrate our logistics and warehouse applications to WPF. Our order grid alone has got more than 50 columns. It would take several seconds to render such a grid in WPF. Sorry, but our users will not accept this; they are used to the rendering speed of the C1TrueDataGrid…

    Why is it faster to render 10.000 extra rows than 3 extra columns?

    Christian

  • Posted 19 September 2017, 10:28 am EST

    There are different things here. Let me see if I can explain them.

    The black background and the huge delay seems a bug to me. It should be second at worst. We should have some layout issue, which might be invalidating/drawing several times. I will investigate it.

    About your questions:

    • The C1DataGrid only draws the cells in the viewport. In WPF and Silverlight, the more visual elements you have to draw, the less performance. So, performance is impacted by your control size and column/row size. In your case, when you add columns, probably the columns are being included inside the viewport. You should experience the same speed if you add for example 6 columns or 600 columns. Adding rows is not decreasing the performance because you were already using the full viewport in that direction, probably. (please correct me)

    • We include two grids in our suite: C1DataGrid and C1FlexGrid. C1FlexGrid is lighter and can be faster in some scenarios. The C1DataGrid follows MS DataGrid object model extending and improving it. C1FlexGrid has its own object model, what give us some extra layout freedom. If I were you, I would try both to see what suite your scenario best.

    • I cannot reproduce the issue the second time, just the first time. And that’s expected as we recycle UIElements. When you maximize for first time, you move from 50 UIElements to 500 and you need to draw them all for first time. Second time you do that, we already have 450 unused UIElements we can reuse, we just need to reset the DataContext. So, a performance difference is expected between first and second time. Problem is, the time should never be so huge, that’s a bug as I said.

    Regards

  • Posted 19 September 2017, 10:28 am EST

    Hi Leo,

    Thank you very much for your comprehensive reply. I did some further testing yesterday, and created our order grid with the C1DataGrid and C1FlexGrid. The latter is – like you said – a lot of faster in my scenario. I would say: C1DataGrid 2 seconds to maximize the window for the first time; C1Flexgrid half a second to maximize the window for the first time.

    I’ve got some additional questions:

    • Can I improve the rendering speed by using a different style / template to reduce the amount of elements in the viewport?

    • I added a classical Filter Bar to the C1DataGrid using the DataGridFilterRow class. Does this work for the C1FlexGrid as well?

    • The Filter Bar is read only somehow. Our order list is a CSLA ReadOnly Business List. Is the Filter Bar read only because of this? Can I create my own filter criteria from the input in the FilterBar and use it in the Load-method of my business object? I don’t want to filter the existing list but load new data.

    • Can I reduce the padding around the textboxes in the Filter Bar? The CellPadding property shows no effect.

    • Can I use the System template to render the grids, so that they look more like the C1TrueDataGrid? Is there a built in theme?

    Thank you very much for your support,

    Christian

  • Posted 19 September 2017, 10:28 am EST

    Hi Christian,

    Glad to see the FlexGrid worked better for your scenario.

    • You can probably improve performance by using bigger rows and columns (so the Viewport will show less cells). You can probably improve cell creation performance by reducing the UIElements used by it, as you said too.

    • The FlexGrid has a different object model, but we include a sample showing how to do a FilterRow as well, IIRC. If not, please post the question in the FlexGrid forum, where will be answered faster than in this one.

    • What do you mean by read only? Did you use the C1.WPF.DataGrid.Fitlers extended dll, or did you create the FilterRow yourself following the help? I suggest the first approach. I do not understand the Load data question. What any filter does in the C1DataGrid, is to set a predicate to the underlying ICollectionView, containing the filter criteria. The ICollectionView is responsible for doing the actual filtering.

    • The CellPadding is being bound to the Margin of the TextBox used to filter. Can you attach a screenshot what are you trying to change?

    • I am not sure what’s the style of the C1TrueDataGrid, but I assume it follows a theme closer to the Windows one. In our WPF suite, we folow the WPF default theme for the controls. In any case, you can use the ClearStyle properties to achieve a simple color customization setting a few brushes in the main control. This is the sample in Silverlight, but the same applies for WPF: http://demo.componentone.com/silverlight/controlexplorer/#DataGrid/ClearStyle

    We are going to include support for some Themes in the V3 release (but targeting .NET 4).

    Hope this helps!

  • Posted 19 September 2017, 10:28 am EST

    Hi Leo,

    I’m sorry, bigger rows and columns wouldn’t work for me: Our dispatchers usually resize the columns in our logistics application to an absolute minimum, to get as much information as possible on the screen. My fear is that scrolling (especially from right to left) gets a little sluggish then, too. I noticed that in my test application.

    For the Filter Bar I used the example from Component One’s blog “New WPF Data Grid: Implementing a Filter Bar” (http://our.componentone.com/2010/07/23/new-datagrid-for-wpf). Maybe this is outdated? Can you please point me to the right place in the help for a custom filter bar? I only found the excel style filtering.

    In my grid I can’t click into the textboxes of the Filter Bar; they are all disabled. I thought this might be because I use a read only collection from the CSLA Business Framework.

    When the user presses Enter in the filter bar, I want to create my own filter string from the input, and pass it on to the load method of my business collection:

    [vb]Dim orders as OrderList = OrderList.Load(myFilterString)[/vb]

    I’ve added the screenshot from the blog to this post. Around the textboxes is an orange frame. I would like to get rid of the frame, so that the textboxes fill the complete cell.

    Sorry, the Silverlight example does not load. “Downloading Sample Module” stops at 62%, then I get “Cannot load C1DataGrid_Demo2010.Appearance component.” I’ll try again tomorrow. Yes, I would like a theme closer to the Windows one.

    Thank you very much

    Christian

  • Posted 19 September 2017, 10:28 am EST

    About the filter row, yes that post might be outdated. You can use the built-in filter row I guess. Please take a look to the samples:

    [Your Documents]ComponentOne SamplesStudio for WPF

    The sample you are looking for is the ControlExplorer, in particular, take a look to the DataGridSamples project, and then look under the Filters folder.

    That said, based on your second requirement, I am not sure the FilterRow will help you. Why do you want to create a custom predicate? Is the one we generate incorrect or do you want a different criteria? Can you explain?

    Regards

    PS. Too bad you couldn’t load the Silverlight sample, it works from my end, and have not listened about other users having the same issue. Strange.

  • Posted 19 September 2017, 10:28 am EST

    Hi Leo,

    Please see the attached sample application and screenshot.

    The Load method of the OrderList passes a special criteria object over the network to the application server. The DataPortal_Fetch method runs on the application server; the access to the database takes place there only. The application itself has no knowledge about / no direct access to the underlying database. (The attached sample is configured that it runs local without a database.)

    In my applications I create a special filter string and pass it to the server. Such a filter string would look like this:

    “[PropertyName1] > ‘Filtertext1’ AND [PropertyName2] = ‘Filterstring2’”

    When the user presses Enter in a filter textbox, I want to create this filter string, pass it over the network to the application server and reload the data from the database. It is not a “Filter the actual content of the grid” but a “Search the database for” scenario…

    The CSLA Framework throws an exception on the attempt of altering a read only business collection. This happens in my attached sample when you enter a text into the filter bar of the first grid: The grid tries to filter the list straightaway by removing items from the list – just after the first key has been pressed. Then it throws a “Filtering rows isn’t allowed” exception.

    Can I turn off this automatic filtering and handle the complete filtering by myself after the user pressed Enter? Like I can do in the C1TrueDataGrid? I can’t change the behaviour of my business objects, because they must work in a mixed WPF and Windows Forms application with new and old code.

    In the second grid of the sample I created the columns myself. There the filter bar is disabled and I can’t enter text at all.

    Thanks again for your help,

    Christian

    PS: I did a reset of my browser settings and the Silverlight sample works now. Something was wrong on my end.

    2011/08/Sample.zip

  • Posted 19 September 2017, 10:28 am EST

    Hi Christian,

    Currently the filter row commits the filter after a delay in order to avoid executing a filter operation for each key pressed event. I added a property named “Delay” which can be set to null to remove that feature, also now the filter row handles the enter key so that it filters when enter key is pressed.

    This changes will be available in the next bug-fix release.

    If you need more flexibility you could implement your own filter row or override the provided one.

    On the other hand when the columns are set in xaml you should specify the property FilterMemeberPath for each colmn in order to enable filtering.

    Regards,

    Alvaro.

  • Posted 19 September 2017, 10:28 am EST

    As a side note, hot fixes are released weekly. This will be available next Monday (version .197).

    Regards

  • Posted 19 September 2017, 10:28 am EST

    Hi Leo,

    Thank you very much for your help! I’m looking forward to the pre-release version with the new property. Do I find it under http://prerelease.componentone.com? Thanks for the tip with FilterMemeberPath.

    Regards,

    Christian

  • Posted 19 September 2017, 10:28 am EST

    Hi Christian,

    Here is the link to the hot-fixes for WPF (we need to make that website look better, I know).

    http://prerelease.componentone.com/hotfixes/WPF/

    Regards

  • Posted 31 October 2018, 1:55 am EST

    I am working with a mobile application and I was not able to create a context for GPU using OpenCL. having error boot device not found and this was out of my mind. after serving for long I found https://hpetechnicalsupportnumber.com/blog/category/hp-system-boot-device-not-found-error/ just have to create a CL Context using the CGLsharegroup.

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels