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

RadTileView only updating one record at a time

1 Answer 57 Views
TileView
This is a migrated thread and some comments may be shown as answers.
Matt
Top achievements
Rank 1
Matt asked on 02 Jun 2016, 07:14 PM

Hello,

 

I have a program I am creating where the tileview represents a collection of computers, with one tile per computer.  The data that backs this is bound as follows;

<telerik:RadTileView
    x:Name="radTileView"
    MaximizeMode="ZeroOrOne"
    ColumnWidth="250"
    ItemsSource="{Binding Data, Source={StaticResource context}}"
    ItemTemplate="{StaticResource ItemTemplate}"
    ContentTemplate="{StaticResource ContentTemplate}"
    IsVirtualizing="True"
    RowHeight="250"
    Grid.Column="2"
    Grid.Row="0"
    Margin="8,1,10,10"
    />

In my ViewModel, Data is an observable collection, like this;

private ObservableCollection<ImagingData> _imagingData = new ObservableCollection<ImagingData>();
public ObservableCollection<ImagingData> Data
{
    get
    {
        return _imagingData;
    }
    set
    {
        _imagingData = value;
        OnPropertyChanged(() => this.Data);
    }
}

Data is updated by a timer event that polls a database backend.  If i simply update Data by replacing it, everything works fine, except it makes for a poor UI experience since the pane resets constantly. To make for a better experience, where tiles stay maximized, and stay where you put them, i implemented a sort of delta sync.  When the timer event pops, I call UpdateData() with the UI dispatcher.  UpdateData copies Data to an array, then adds new records, deletes records that are not in scope anymore, and updates fields on records that already exist.  it is a crude proof of concept, but here it is;

private void UpdateData(ImagingData[] newItems, ImagingData[] existing)
{
    //var dataArray = _imagingData.ToArray();
    foreach (var item in existing)
    {
        var matchedItem = newItems.Where(c => c.ComputerName == item.ComputerName).FirstOrDefault();
 
        if (matchedItem == null)
            Data.Remove(item);
    }
 
    foreach (var item in newItems)
    {
        var matchedItem = existing.Where(c => c.ComputerName == item.ComputerName).FirstOrDefault();
 
        if(matchedItem == null)
        {
           Data.Add(item);
            return;
        }
 
        matchedItem.ImagingPasses = item.ImagingPasses;
        matchedItem.LastKnownActivity = item.LastKnownActivity;
        matchedItem.ImagingState = item.ImagingState;
    }
 
    OnPropertyChanged("Data");
}

The problem I am having that when i use this method, only 1 record is added to the Data collection each time the update timer fires, even though I have confirmed that the update loop does iterate over all the members.  Visually, you see one tile appear, then the next, then the next, etc, separated by one timer iteration.  I have tried all manner of different ways to remedy this but nothing seems to work.

1 Answer, 1 is accepted

Sort by
0
Matt
Top achievements
Rank 1
answered on 03 Jun 2016, 03:49 PM
Nevermind,  this was a really stupid bug on my part.  After the new record it added, it should be "continue"
not "return".
Tags
TileView
Asked by
Matt
Top achievements
Rank 1
Answers by
Matt
Top achievements
Rank 1
Share this question
or