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

Updating GridView as ObservableCollection is Built

5 Answers 137 Views
GridView
This is a migrated thread and some comments may be shown as answers.
David Cecil
Top achievements
Rank 1
David Cecil asked on 23 Mar 2010, 02:40 AM
Hello,

We're working on a project to pull data from servers.  The code goes over the network to each server of interest and retrieves some server information (i.e. name, Operating System, etc.) which in turn is added to the ObservableCollection.  Everything works fine; however, it can take several minutes to go to each server and pull back the data.  Therefore, we would like to populate the gridview as the data is returned.  For example...application retrieves the name of server 1, the gridview displays server 1 data while in the background server 2 data is retrieved and displayed once it returns, etc.

So here is what we've tried with Gridview bound to an ObservableCollection.

Retrieving the data with a backgroundworker (which works, but the data still does not display on the grid as retrieved).
Tried other Data Types (DataSet, List, etc.) - they all work but all of the data has to be retrieved before being displayed.
Looked at the OnCollectionChanged event and as each server is queried and populated into the ObservableCollection - the event it fired.
Tried changing the DataLoadMode to Asynchronous

Below is the code behind...

using System;  
using System.Collections.Generic;  
using System.Collections.ObjectModel;  
using System.Collections.Specialized;  
using System.ComponentModel;  
using System.DirectoryServices;  
using System.Linq;  
using System.Text;  
using System.Threading;  
using System.Windows;  
using System.Windows.Controls;  
using System.Windows.Data;  
using System.Windows.Documents;  
using System.Windows.Input;  
using System.Windows.Media;  
using System.Windows.Media.Imaging;  
using System.Windows.Shapes;  
using System.Windows.Threading;  
using Telerik.Windows.Controls;  
 
namespace TestXmlSerialize123  
{  
    /// <summary>  
    /// Interaction logic for Window2.xaml  
    /// </summary>  
    public partial class Window2 : Window  
    {  
        public Window2()  
        {  
            InitializeComponent();  
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);  
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);  
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);  
            //worker.WorkerReportsProgress = true;  
            //this.radGridView2.IsBusy = true;  
            DomainControllerList.CollectionChanged += OnCollectionChanged;  
 
 
        }
        #region Variables  
          
        BackgroundWorker worker = new BackgroundWorker();
        #endregion  
 
        private void worker_DoWork(object sender, DoWorkEventArgs e)  
        {  
            //Thread.Sleep(5000);  
            FetchDomainControllers();  
 
        }  
 
        private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)  
        {  
            this.radGridView2.ItemsSource = e.UserState;  
 
        }  
 
        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)  
        {  
            this.radGridView2.ItemsSource = DomainControllerList;  
        }  
 
        private ObservableCollection<DADdomainControllers> _domainControllerList = new ObservableCollection<DADdomainControllers>();  
        public ObservableCollection<DADdomainControllers> DomainControllerList  
        {  
            get { return _domainControllerList; }  
        }  
 
        private void FetchDomainControllers()  
        {  
 
 
 
            DirectoryEntry rootDSE = new DirectoryEntry("LDAP://rootDSE");  
            string configurationNamingContext = (string)rootDSE.Properties["configurationNamingContext"].Value;  
 
            DirectoryEntry deConfig = new DirectoryEntry("LDAP://" + configurationNamingContext);  
            DirectorySearcher dsConfig = new DirectorySearcher(deConfig);  
            dsConfig.Filter = "(objectClass=ntDSDSA)";  
 
            SearchResultCollection results = dsConfig.FindAll();  
 
            foreach (SearchResult Result in results)  
            {  
 
                DirectoryEntry deDomain = Result.GetDirectoryEntry();  
 
                if (deDomain != null)  
                {  
 
                    string _dnsHostName = deDomain.Parent.Properties["DNSHostName"].Value.ToString();  
                    string _serverReference = deDomain.Parent.Properties["serverReference"].Value.ToString();  
                    _domainControllerList.Add(new DADdomainControllers { dnsHostName = _dnsHostName, distinguishedName = _serverReference });  
                    //radGridView2.Dispatcher.Invoke(DispatcherPriority.Normal,(Action)(() => { radGridView2.ItemsSource = DomainControllerList; }));  
                    //this.radGridView2.ItemsSource = DomainControllerList;  
 
                }  
            }  
 
 
 
        }  
 
        public class DADdomainControllers  
        {  
            public string dnsHostName {getset;}  
            public string distinguishedName {getset;}  
        }  
 
        private void Window_Loaded(object sender, RoutedEventArgs e)  
        {  
 
                          
        }  
 
        private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)  
        {  
            //MessageBox.Show("Collection Changed");  
              
 
        }  
 
        private void radGridView2_Loaded(object sender, RoutedEventArgs e)  
        {  
            Thread.Sleep(3000);  
            worker.RunWorkerAsync();  
        }  
 
    }  

Not much to the XAML but here it is...

<Window x:Class="TestXmlSerialize123.Window2" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" 
    Title="Window2" Height="600" Width="800" Loaded="Window_Loaded">  
    <Grid> 
        <telerik:RadGridView Name="radGridView2" DataLoadMode="Asynchronous" Loaded="radGridView2_Loaded" /> 
    </Grid> 
</Window> 


5 Answers, 1 is accepted

Sort by
0
Vlad
Telerik team
answered on 23 Mar 2010, 07:45 AM
Hello,

Can you verify using the debugger if this method is raised:

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)  
{  
   this.radGridView2.ItemsSource = DomainControllerList;  
}

and what you have have for the grid ItemsSource?

All the best,
Vlad
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
David Cecil
Top achievements
Rank 1
answered on 23 Mar 2010, 03:34 PM
In regards to the method (this.radGridView2.ItemsSource = DomainControllerList;), yes it is raised and DomainControllerList contains data.

I'm not sure how to answer the question "what you have for the grid ItemsSource?" as the ItemsSource is listed in the same Method above - DomainControllerList which is an ObservableCollection.

To clarify what we're after - if we were to change this as an output to command line, the data would appear as it was retrieved and begin a new line until complete, we would like the same effect in the grid.  The reason we want to use the gridview is because of all of the other features (sorting, filtering, grouping, counts, etc.).

 

0
Vlad
Telerik team
answered on 23 Mar 2010, 03:44 PM
Hi,

I'm not sure what is causing this at your end however you use alternatively IsBusy property of the grid to indicate that the grid is still not bound.

Greetings,
Vlad
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
David Cecil
Top achievements
Rank 1
answered on 23 Mar 2010, 03:58 PM
We've used the IsBusy and it's just not a good user experience.  With infrastructure applications, you like to see the data as it's retrieved.  For instance with Active Directory Users and Computers or LDAPAdministrator or ADSIEDIT all these tools fetch the data and display them as retrieved.  If we were retrieving user objects, you wouldn't want to see a indeterminate progress indicator spinning around for 10-30 minutes (which it can take this long depending on network speed) or even a status message saying "Retrieving server/user information...user1: Please wait".

It seems this should be relatively easy to "refresh" the gridview as the collection is being added to.  Once again, the CollectionChanged event is being fired each time a object is being added to the Collection.  Is there not a way to "refresh" the gridview as this happens to display the ObjectCollection? 
0
Vlad
Telerik team
answered on 23 Mar 2010, 04:24 PM
Hi,

I've attached an example application with grid bound to ObservableCollection and adding items on every second through BackgroundWorker.

Regards,
Vlad
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
Tags
GridView
Asked by
David Cecil
Top achievements
Rank 1
Answers by
Vlad
Telerik team
David Cecil
Top achievements
Rank 1
Share this question
or