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

CollectionChanged event doesn't update the Grid

8 Answers 402 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Paul
Top achievements
Rank 1
Paul asked on 25 Jul 2012, 09:42 PM
Hello,

I have been struggling with the GridView to get it to display my data as my ObservableCollection changes. It appears that the grid is only updating when the user moves a scroll bar. How can I make my grid update as my collection does, without messing up my scroll position. I attempted using the Rebind() method to get it to refresh, but the scroll bar resetting is unacceptable.

Here is a little information about my setup.

I am using the WPF Rad Controls Q2 2012 edition.

My Observable collection is a two dimensional collection that looks like this:

private ObservableCollection<ObservableCollection<LogField>> _RowData;
public ObservableCollection<ObservableCollection<LogField>> RowData
{
    get { return _RowData; }
    set
    {
        if (value != _RowData)
        {
            _RowData = value;
            onPropertyChanged(this, "RowData");
        }
    }
}

Here is what the LogField Class looks like:

public class LogField : INotifyPropertyChanged
    {
        private byte _HighlighFlag;
        public byte HighlightFlag
        {
            get { return _HighlighFlag; }
            set
            {
                if (value != _HighlighFlag)
                {
                    _HighlighFlag = value;
                    onPropertyChanged(this, "HighlightFlag");
                }
            }
        }
 
        private string _Value;
        public string Value
        {
            get { return _Value; }
            set
            {
                if (value != _Value)
                {
                    _Value = value;
                    onPropertyChanged(this, "Value");
                }
            }
        }
 
        private string _DisplayUnits;
        public string DisplayUnits
        {
            get { return _DisplayUnits; }
            set
            {
                if (value != _DisplayUnits)
                {
                    _DisplayUnits = value;
                    onPropertyChanged(this, "DisplayUnits");
                }
            }
        }
 
        private string _BaseUnits;
        public string BaseUnits
        {
            get { return _BaseUnits; }
            set
            {
                if (value != _BaseUnits)
                {
                    _BaseUnits = value;
                    onPropertyChanged(this, "BaseUnits");
                }
            }
        }
 
        private byte _FieldType;
        public byte FieldType
        {
            get { return _FieldType; }
            set
            {
                if (value != _FieldType)
                {
                    _FieldType = value;
                    onPropertyChanged(this, "FieldType");
                }
            }
        }
 
        private string _FieldFormat;
        public string FieldFormat
        {
            get { return _FieldFormat; }
            set
            {
                if (value != _FieldFormat)
                {
                    _FieldFormat = value;
                    onPropertyChanged(this, "FieldFormat");
                }
            }
        }
 
        private int _SelectOffset;
        public int SelectOffset
        {
            get { return _SelectOffset; }
            set
            {
                if (value != _SelectOffset)
                {
                    _SelectOffset = value;
                    onPropertyChanged(this, "SelectOffset");
                }
            }
        }
 
        private int _UnitNumber;
        public int UnitNumber
        {
            get { return _UnitNumber; }
            set
            {
                if (value != _UnitNumber)
                {
                    _UnitNumber = value;
                    onPropertyChanged(this, "UnitNumber");
                }
            }
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
        private void onPropertyChanged(object sender, string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
            }
        }
    }


I am setting up the columns manually and here is what the column setup and binding look like.

// Initialize the radGridView with the propper settings for a log screen.
int columnIndex = 0;
thisMMGridView.Height = 280;
LogScreen logScreen = (LogScreen)thisMMGridView.CurrentScreen;
thisMMGridView.radGridView.AutoGenerateColumns = false;
thisMMGridView.radGridView.Columns.Clear();
 
// Build the columns based on the headerStrings
foreach (string headerString in logScreen.ColumnHeaderStrings)
{
    GridViewDataColumn column = new GridViewDataColumn();
 
    // Create the column header
    TextBlock headerText = new TextBlock();
    headerText.Text = headerString;
    headerText.TextWrapping = TextWrapping.Wrap;
    headerText.TextAlignment = TextAlignment.Left;
    headerText.Padding = new Thickness(1, 0, 2, 0);
    column.HeaderCellStyle = thisMMGridView.TryFindResource("AlarmGridViewHeaderCellStyle") as Style;
    column.Header = headerText;
    column.UniqueName = headerString;
    thisMMGridView.radGridView.Columns.Add(column);
    // Bind the column to it's data
    column.DataMemberBinding = new Binding("["+ columnIndex.ToString() +"].Value");
     
    // Bump the column index that is used for the columnBind
    columnIndex++;
}
 
// Freeze the time & date columns so they are always visible
if (thisMMGridView.radGridView.Columns[1].UniqueName == "DATE")
{
    thisMMGridView.radGridView.FrozenColumnCount = 2;
}
else
{
    thisMMGridView.radGridView.FrozenColumnCount = 1;
}
 
// Set the ItemsSource property of the grid to the data collection.
thisMMGridView.radGridView.ItemsSource = thisMMGridView.Unit.LogData.RowData;


I have wasted a lot of time on this issue and I am just looking for a solution, so I can move forward. 

Hope to hear something soon,
Brian

8 Answers, 1 is accepted

Sort by
0
Dimitrina
Telerik team
answered on 26 Jul 2012, 08:50 AM
Hello,

 Generally the ScrollBar will be reset to the top of the GridView only when the bound collection is Reset. So, when you change the bound collection, then the GridView does not updated with the changes you have done. May I ask you let us know some additional details on how do you update the collection? When the CollectionChanged event is raised, what is the CollectionChangedAction?  

All the best,
Didie
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Paul
Top achievements
Rank 1
answered on 26 Jul 2012, 03:23 PM
Hi Didie,

Thanks for your response.

The CollectionChanged Action is always "Add". I am updating my collection in code by recieving data through my WCF service and that processing the data into my ObservableCollection called RowData.

The scroll bar only resets if I try to manually force the refresh  by calling Rebind() on the RadGridView. The alternative seems to be that if I let the control handle the updates itself I never see any data in my grid until I attempt to scroll. The first scroll action seems to bring all of my data into my grid (See previously attached images). The thing I am trying to fix is to make the collection appear without the user needing to attempt to scroll.

I think this is a side affect of creating my columns manually and setting a DataMemberBinding before the binding source is created. The binding source gets created at runtime and the grid doesn't seem to be trying to reevaluate the binds until the grid is scrolled.
0
Dimitrina
Telerik team
answered on 27 Jul 2012, 08:35 AM
Hello, 

 We have introduced some improvements in loading data with our Service Pack. May I ask you to check what the behaviour is with the latest binaries? If the problem still remains, may I ask you to isolate the issue in a demo project which we could debug locally to check what is wrong?

All the best,
Didie
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Paul
Top achievements
Rank 1
answered on 27 Jul 2012, 03:40 PM
I am downloading and installing the service pack now. I looked at the release notice and didn't see any mention of improvements in loading data. I'll give it a shot anyways and report back when I am done.
0
Paul
Top achievements
Rank 1
answered on 27 Jul 2012, 05:11 PM
I can confirm that I am having the same issue with Q2 2012 SP1 released on 7/25/2012

I will work on reproducing this in a demo and hope to have this to you guys sometime this weekend.
0
Dimitrina
Telerik team
answered on 30 Jul 2012, 05:10 AM
Hi,

 Thank you for the update. We will further investigate the problem once you send to us a demo project.

All the best,
Didie
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Paul
Top achievements
Rank 1
answered on 31 Jul 2012, 07:09 PM
Hello,

Sorry for the late response. I was able to solve my problem before I created my reproduction of the problem. The solution was to create and fill the 2nd dimension of my collection whenever I created my first dimension. 

ObservableCollection<ObservableCollection<LogField>> LogRow = new ObservableCollection<ObservableCollection<LogField>>();

Example of how I was filling collection before:

ObservableCollection<LogField> Row = new ObservableCollection<LogField>();

LogRow.Add(Row);
foreach (LogField field in CommunicationsCollection)
{
Row.Add(field);
}

Example of how I am filling the collection now:

int columnIndex = 0;
ObservableCollection<LogField> Row = new ObservableCollection<LogField>(int NumberOfColumns);

LogRow.Add(Row);
foreach (LogField field in CommunicationsCollection)
{
Row[rowIndex][columnIndex].Value = field.Value;
columnIndex++;
} 

The main difference is that when I initialize the Row collection I initialize the 2nd dimension (NumberOfColumns) with a blank LogField and then I set the values.

The reason I think this works is because the control is only getting the collection changed event when the first dimension changes (adding a row) and not when I fill the row. So it would evaluate the bind seconds before the 2nd dimension existed. Now that i create them at the same time the bind resolves properly and the grid is working smoothly.

Thanks,
Brian
0
Dimitrina
Telerik team
answered on 01 Aug 2012, 06:17 AM
Hello Brian,

I am glad to hear that you have resolved the problem. Thank you for sharing the solution with the community.

Kind regards,
Didie
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Tags
GridView
Asked by
Paul
Top achievements
Rank 1
Answers by
Dimitrina
Telerik team
Paul
Top achievements
Rank 1
Share this question
or