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

Problem using progressbar with double click event of treeviewitem

1 Answer 78 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
fred williams
Top achievements
Rank 1
fred williams asked on 30 Apr 2011, 08:35 PM
I'm creating a windows explorer-like application using a treeview control. When a user double clicks a treeview item, it reloads the treeview with the new directory and its subfolders and files. Works fine. 

I tried to add a progress bar to it and have it update using the backgroundworker object, like this msdn example:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

using this code for the mouse double click event of the treeview items:
private void tvDirectory_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
 
    RadTreeViewItem item = (RadTreeViewItem)((RadTreeView)sender).SelectedContainer;
    string arg = item.Header.ToString();
    
    wrkDeploy.RunWorkerAsync(arg);
 
}

and this for the background worker eventhandlers:
  BackgroundWorker wrkDeploy;
public MainWindow()
        {
            InitializeComponent();
            this.wrkDeploy = new BackgroundWorker();
            wrkDeploy.RunWorkerCompleted += new RunWorkerCompletedEventHandler(wrkDeploy_RunWorkerCompleted);
            wrkDeploy.DoWork += new DoWorkEventHandler(wrkDeploy_DoWork);
            wrkDeploy.ProgressChanged += new ProgressChangedEventHandler(wrkDeploy_ProgressChanged);
        }
 
  private void wrkDeploy_DoWork(object sender, DoWorkEventArgs e)
        {
            string item = e.Argument.ToString();
            if (isDirectory(_currentPath + item.ToString()))
            {
 
                _currentPath += @"\";
                DirectoryInfo di = new DirectoryInfo(_currentPath);
                DirectoryInfo[] directories = null;
                int cnt = 0;
                int maxCnt = 0;
                try
                {
                    directories = di.GetDirectories();
                    FileInfo[] files = di.GetFiles();
                    maxCnt = directories.Length + files.Length;
                    while (cnt < maxCnt)
                    {
 

 
                        foreach (DirectoryInfo dInfo in directories)
                        {
 
                            RadTreeViewItem tvDirectoryItem = new RadTreeViewItem() { Header = dInfo.Name, DefaultImageSrc = "folder_icon.gif", ItemsOptionListType = OptionListType.OptionList, OptionType = OptionListType.None };
                            tvDirectory.Items.Add(tvDirectoryItem);
                            cnt += 1;
                            int percentComplete = (cnt / maxCnt) * 100;
                            wrkDeploy.ReportProgress(percentComplete);
                        }
                        if (files.Length > 0 && cnt == 0)
                        {
 
                            RadTreeViewItem root = new RadTreeViewItem() { Header = "Select/Deselect All Files in Folder" };
                            root.Checked += new System.EventHandler<Telerik.Windows.RadRoutedEventArgs>(tvDirectory_itemChecked);
                            root.Unchecked += new System.EventHandler<Telerik.Windows.RadRoutedEventArgs>(tvDirectory_itemUnChecked);
                            tvDirectory.Items.Add(root);
                        }
 
                        foreach (FileInfo fInfo in files)
                        {
 
                            RadTreeViewItem tvFileItem = new RadTreeViewItem() { Header = fInfo.Name, ItemsOptionListType = OptionListType.CheckList, OptionType = OptionListType.CheckList };
                            tvFileItem.Checked += new EventHandler<Telerik.Windows.RadRoutedEventArgs>(tvDirectory_fileChecked);
                            tvFileItem.Unchecked += new EventHandler<Telerik.Windows.RadRoutedEventArgs>(tvDirectory_fileUnChecked);
                            tvDirectory.Items.Add(tvFileItem);
                            cnt += 1;
                            int percentComplete = (cnt / maxCnt) * 100;
                            wrkDeploy.ReportProgress(percentComplete);
                        }
                    }
                }
                catch (UnauthorizedAccessException uae) { }
            }
        }
        private void wrkDeploy_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

        }
        private void wrkDeploy_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.ProgressBar1.Value = (double)e.ProgressPercentage;
        }

I get an error stating "The calling thread must be STA, because many UI components require this." when I run it on the line that instantiates the first treeview item in my do work event handler
"RadTreeViewItem tvDirectoryItem = new RadTreeViewItem() { Header = dInfo.Name, DefaultImageSrc = "folder_icon.gif", ItemsOptionListType = OptionListType.OptionList, OptionType = OptionListType.None };"

Help please, thanks.

1 Answer, 1 is accepted

Sort by
0
Hristo
Telerik team
answered on 05 May 2011, 09:00 AM
Hi fred williams,

The WPF is designed in the way that only the UI thread has access to the visual object. You should use Dispatcher.BeginInvoke method where dealing with the UI objects in order to fix the issue. You can take a look a the following article in msdn: http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.begininvoke.aspx

Hope this helps. Please let us know if you need more help.

Greetings,
Hristo
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
TreeView
Asked by
fred williams
Top achievements
Rank 1
Answers by
Hristo
Telerik team
Share this question
or