We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. (Last updated on: November 16, 2018).
Unfortunately, activation email could not send to your email. Please try again.
Syncfusion Feedback

sfdatagrid is not rendering correctly after I allow sorting

Thread ID:

Created:

Updated:

Platform:

Replies:

132901 Sep 27,2017 07:51 PM UTC Oct 13,2017 05:47 AM UTC WPF 8
loading
Tags: SfDataGrid
xudongli
Asked On September 28, 2017 12:58 PM UTC

my binding data was a dictionary of dictionary, so I am apply my custom sorting class, my xaml is below
               


the code above works fine, but after I set  AllowSorting="True" , table rendering is wrong and it's not working work correctly even if I apply my own customer sorting class, it that a bug?  really hope someone could help me out.

Gnanasownthari Thirugnanam [Syncfusion]
Replied On September 29, 2017 01:12 PM UTC

Hi xudongli, 
 
Could you please provide simple application or elaborate your view model on how you have bind the ItemSource as Dictionary of Dictionary, so that we can use the same model from our end for reproducing the reported issue. Also in the meantime, could you please try your application by setting the UseBindingValue as true for the GridColumns and provide your confirmation whether it resolves your reported issue. 
 
Please refer the below UG link for more details about UseBindingValue property 
 
Regards, 
Gnanasownthari T. 


xudongli
Replied On October 3, 2017 03:05 PM UTC

Hi 

thanks for replying, I try to use the link you send me, it works if I set autocolumn generation to false but right now I am using my own cellrender class to create custom column, my binding data is a dictionary<srting, EntityItem> my entityitem class has fields below


public sealed class EntityItem

    {

        public object Value { get; private set; }

        public object OldValue { get; private set; }

        public Type Type { get; private set; }

        public string DisplayValue { get; set; }

        public Brush Background { get; set; }

        public SolidColorBrush AnimateBackground { get; set; }

        public Brush Foreground { get; set; }

}

and I have my custom cellrender below
 public class CerebroTextBoxBaseGridCellRenderer : GridVirtualizingCellRenderer<TextBox, TextBox>
    {
        protected override TextBox OnCreateDisplayUIElement()
        {
            
            TextAlignmentToHorizontalAlignment(TextAlignment.Center);
            return new TextBox();
        }

        protected override TextBox OnCreateEditUIElement()
        {
            return null;
        }

        protected virtual void InitAppearence(TextBox element)
        {
            element.BorderThickness = new Thickness(0);
            element.FontSize = 14;

            element.Padding = new Thickness(5, 10, 5, 10);
            element.TextAlignment = TextAlignment.Center;
            element.HorizontalAlignment = HorizontalAlignment.Stretch;
            element.Width = 105;
        }

        public override void OnInitializeDisplayElement(DataColumnBase dataColumn, TextBox uiElement, object dataContext)
        {
            InitAppearence(uiElement);
            
            SetDisplayBinding(uiElement, dataColumn.GridColumn, dataContext);
        }

        public virtual void SetDisplayBinding(TextBox element, GridColumn column, object dataContext)
        {
            var customColumn = (CerebroTextColumn)column;


            var binding = new System.Windows.Data.Binding
            {

                Path = new PropertyPath(customColumn.MappingName + ".DisplayValue"),
                Source = dataContext,
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
                Converter = new NumberConverter()
            };

            element.SetBinding(TextBox.TextProperty, binding);

            var fgBinding = new System.Windows.Data.Binding
            {
                Path = new PropertyPath(customColumn.MappingName + ".Foreground"),
                Source = dataContext,
            };

            element.SetBinding(TextBox.ForegroundProperty, fgBinding);

            var dgBinding = new System.Windows.Data.Binding
            {
                Path = new PropertyPath(customColumn.MappingName + ".Background"),
                Source = dataContext,
            };
            
            element.SetBinding(TextBox.BackgroundProperty, dgBinding);
        }
        
    }

In my view mode I listen to the AutoGeneratingColumnArgs event and generate column programmicly there 
private void CreateRiskSymbolColumns(EventToCommandArgs args)
        {
            var eventArgs = args.EventArgs as AutoGeneratingColumnArgs;
            var columnName = eventArgs.Column.MappingName;

            var entity = Entities.GetItemProperties().Find(columnName, true) as EntityPropertyDescriptor;

            if (entity == null) return;

            if (columnCount < ColumnsNum)
            {
                eventArgs.Column = _columnControlFactory.CreateColumnControl(entity.CellType, columnName);
                eventArgs.Column.UseBindingValue = true;

            }
            else
            {
                eventArgs.Cancel = true;
            }

        }

I tried your advise there to set UseBindingValue to true but it's still not working. hopefully the info I provided give you the idea what I want to achieve

Gnanasownthari Thirugnanam [Syncfusion]
Replied On October 9, 2017 11:31 AM UTC

Hi xudongli, 

On analyzing your given code snippet we suspect that you had set the whole EntityCollection as MappingName instead of BusinessObject for created columns. In SfDataGrid Sorting operation take place based  upon the underlying object so that we suggested you to set an underlying business object as MappingName as like below code example. 

private void datagrid_AutoGeneratingColumn(object sender, AutoGeneratingColumnArgs e) 
{ 
    e.Column = new CerebroTextColumn() { MappingName = "Value.DisplayValue" }; 
 

We have prepared the sample based on your code snippet , you can download the same from below mentioned location. 

Sample location: 


Regards, 
Gnanasownthari T. 
 


xudongli
Replied On October 9, 2017 03:07 PM UTC

Hi Gnanasownthari 


thanks for replying me back, the binding is working correct, I am not binding the whole collection but a single EntityItem object, that's why I customise my SetDisplayBinding function,

  1. what I observe so far is that if my sfdatagrid only have few rows of data where the scroll  view doesn't automaticlly apply on the sfdatagrid, all works fine, but if I got more data in the grid,  scroll  view will shows up and my data messed up, rows on the tail will be replaced by rows already showed on former rows. and it only happen when I set AllowSorting="True".

<Grid>

            <syncfusion:SfDataGrid  AllowSorting="True">

     </Grid>


  1. But if I put sfdatagrid inside a ScrollViewer it works, but datagrid will be very slow for sorting which I don't want.

<ScrollViewer x:Name="ScrollViewer">

        <Grid>

            <syncfusion:SfDataGrid  >

     </Grid>

</ScrollViewer >


So I am wondering if this problem is happening because I am using customised column and cell class. I am following the tutorial of link below, everything is working until I want to apply sorting function. because it also workings when I am using building text column class the code below works fine, I am thinking is that because sorting is not supported in customised cell class, or did I missing something?

<Syncfusion:SfDataGrid.Columns>

                    <Syncfusion:GridTextColumn MappingName="NetOpenPos.DisplayValue" UseBindingValue="True"/>

                    <Syncfusion:GridTextColumn MappingName="RealPnL.DisplayValue" UseBindingValue="True"/>


          </Syncfusion:SfDataGrid.Columns>

I have been searching around for quite a long time and haven't got any clues to solve this. the temporary fix is wrapp datagrid inside ScrollViewer, but is makes my program very slow


best

lee



xudongli
Replied On October 9, 2017 04:05 PM UTC

Hi Gnanasownthari 

please check my previous reply, and in  order to let me have better idea how to recreate the problem I just modified your code by adding more initial items and make the height of datagrid smaller you can see the duplated problem and missing data.


best

lee


Attachment: SfDataGridDemo_Sorting364615328_fc31b349.zip

Gnanasownthari Thirugnanam [Syncfusion]
Replied On October 10, 2017 01:42 PM UTC

Hi Lee,   
  
We have noticed that you have set the source for Binding in your code example. By default, SfDataGrid supports UI virtualization, it creates the UI elements only for view items and it reuses the created elements in scrolling and sorting cases only. The DataContext will be changed for those items.   
 
Now we have modified the sample by commenting the source in binding.   
C#   
public virtual void SetDisplayBinding(TextBox element, GridColumn column, objectdataContext)   
    {   
        var customColumn = (CerebroTextColumn)column;   
   
        var binding = new System.Windows.Data.Binding   
        {   
            Path = new PropertyPath(customColumn.Propertyvalue + ".DisplayValue"),   
            //Source = dataContext,   
            UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,   
            Converter = new NumberConverter()   
        };   
   
        element.SetBinding(TextBox.TextProperty, binding);   
              
   
        var fgBinding = new System.Windows.Data.Binding   
        {   
            Path = new PropertyPath(customColumn.Propertyvalue + ".Foreground"),   
            //Source = dataContext,   
        };   
   
        element.SetBinding(TextBox.ForegroundProperty, fgBinding);   
   
        var dgBinding = new System.Windows.Data.Binding   
        {   
            Path = new PropertyPath(customColumn.Propertyvalue + ".Background"),   
            //Source = dataContext,   
        };   
   
        element.SetBinding(TextBox.BackgroundProperty, dgBinding);   
    }   
}   
  
   
In another way, if you want to define source in binding you need to override the CanUpdateBinding method and return as true like below code example. But this will affect the performance when you are using more number of columns.   
C#   
public override bool CanUpdateBinding(GridColumn column)   
{   
    //If you set the source in binding need to override this method and return true.   
    return true;   
}   
  
  
You can download the modified sample from below mentioned location.   
  
Sample location:   

 
 
Regards,   
Gnanasownthari T.   



xudongli
Replied On October 12, 2017 09:54 AM UTC

Thanks Gnanasownthari , it works and really appreciate for your help! save us a lot of time


best

lee


Gnanasownthari Thirugnanam [Syncfusion]
Replied On October 13, 2017 05:47 AM UTC

Hi lee, 
 
Thank you for your update, 
 
Please let us know if you need any further assistance on this. 
 
Regards, 
Gnanasownthari T.  
 


CONFIRMATION

This post will be permanently deleted. Are you sure you want to continue?

Sorry, An error occured while processing your request. Please try again later.

Warning Icon You are using an outdated version of Internet Explorer that may not display all features of this and other websites. Upgrade to Internet Explorer 8 or newer for a better experience.Close Icon

;