dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5

Thread: Update Combobox - Delegates

  1. #1
    Join Date
    Apr 2007
    Location
    Florida
    Posts
    403

    Update Combobox - Delegates

    Hi, I tried marking my previous post as Un-Resolved but couldnt figure out how, so i made a new one, sorry!

    Anyways,

    The solution given to me earlier which was to use delegates worked fine for adding items to a combobox through string entries.

    However, I'm currently running into a problem with adding items from a dataset. With the following code:

    Code:
            private void InitializeBuildManager()
            {
                if (comboBoxGameTitle.InvokeRequired)
                {
                    this.comboBoxGameTitle.Invoke(new UpdateBuildListInvoker(InitializeBuildManager));
                }
                else
                {
                    comboBoxGameTitle.DataSource = _WebService.GetAllGameTitles().Tables[0];
                    AddToLog("Build Data Loaded Successfuly");
                }            
            }

    This actually freezes my main form until it's finished loading. The goal of using another thread was to have it leave my main form intact during the download of information.

    The way im starting the thread is:

    (MainForm_Load)
    Code:
                AddToLog("Downloading Build List Data...");
                _LoadBuildListThread = new Thread(InitializeBuildManager);
                _LoadBuildListThread.Start();
    -MarioCatch

  2. #2
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    1,080

    Re: Update Combobox - Delegates

    The whole point of using multi-threading is to do as little work as possible in the UI thread. That code of yours simply delegates back to the UI thread and does all the work there. What's the point of the worker thread then? This is from my post to your previous thread:
    The way to access controls from a worker thread is indirectly via delegation. First you should declare a method that performs only the control access.
    What is the long-running operation in there? It's this:
    Code:
    _WebService.GetAllGameTitles()
    so that part needs to be done on the worker thread. The ONLY reason to use delegation is to set the DataSource property of the ComboBox, so you should be doing all the work to get the DataTable on the worker thread, then the ONLY thing you do on the UI thread is assign that DataTable to the DataSource property of the ComboBox. This bit stays the same:
    Code:
    AddToLog("Downloading Build List Data...");
    _LoadBuildListThread = new Thread(InitializeBuildManager);
    _LoadBuildListThread.Start();
    This part:
    Code:
    private void InitializeBuildManager()
    {
        if (comboBoxGameTitle.InvokeRequired)
        {
            this.comboBoxGameTitle.Invoke(new UpdateBuildListInvoker(InitializeBuildManager));
        }
        else
        {
            comboBoxGameTitle.DataSource = _WebService.GetAllGameTitles().Tables[0];
            AddToLog("Build Data Loaded Successfuly");
        }            
    }
    is reduced to this:
    Code:
    private void InitializeBuildManager()
    {
    	DataTable dataSource = _WebService.GetAllGameTitles().Tables[0];
    
    	LoadComboBoxDataSource(dataSource);
    	AddToLog("Build Data Loaded Successfuly");
    }
    and now you add a new method that performs the delegation and ONLY the minimum of work on the UI thread:
    Code:
    private delegate void DataTableMethodInvoker(DataTable table);
    
    private void LoadComboBoxDataSource(DataTable dataSource)
    {
    	if (comboBoxGameTitle.InvokeRequired)
    	{
    		comboBoxGameTitle.Invoke(new DataTableMethodInvoker(LoadComboBoxDataSource), dataSource);
    	}
    	else
    	{
    		comboBoxGameTitle.DataSource = dataSource;
    	}
    }
    Now the grunt work is done on the worker thread and the bare minimum, i.e. ONLY the control access, is done on the UI thread.
    Tutorials: Home & Learn | Start VB.NET | Learn VB.NET | C# Station | GotDotNet | Games in VB.NET 101 Samples: 2002 | 2003 | 2005 | More .NET 2.0 (VB.NET, C#) Articles: VB.NET | C# | ASP.NET | MoreFree Components: WFC | XPCC | ElementsEx | VBPP | Mentalis | ADO.NET/MySQL | VisualStyles | Charting (NPlot, ZedGraph) | iTextSharp (PDF) | SDF (CF) ● Free Literature: VB 2005 (eBook) | VB6 to VB.NET (eBook) | MSDN Magazine (CHM format) ● Bookmarks: MSDN | WinForms .NET | ASP.NET | WinForms FAQ | WebForms FAQ | GotDotNet | Code Project | DevBuzz (CF) ● Code Converter: C#/VB.NET | VB.NET/C# | VS 2005 add-in

  3. #3
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    1,080

    Re: Update Combobox - Delegates

    By the way, if you're using .NET 2.0+ then you really should use a BackgroundWorker for stuff like this. There's no delegation required in simple cases because the ProgressChanged and RunWorkerCompleted events are raised on the UI thread.
    Tutorials: Home & Learn | Start VB.NET | Learn VB.NET | C# Station | GotDotNet | Games in VB.NET 101 Samples: 2002 | 2003 | 2005 | More .NET 2.0 (VB.NET, C#) Articles: VB.NET | C# | ASP.NET | MoreFree Components: WFC | XPCC | ElementsEx | VBPP | Mentalis | ADO.NET/MySQL | VisualStyles | Charting (NPlot, ZedGraph) | iTextSharp (PDF) | SDF (CF) ● Free Literature: VB 2005 (eBook) | VB6 to VB.NET (eBook) | MSDN Magazine (CHM format) ● Bookmarks: MSDN | WinForms .NET | ASP.NET | WinForms FAQ | WebForms FAQ | GotDotNet | Code Project | DevBuzz (CF) ● Code Converter: C#/VB.NET | VB.NET/C# | VS 2005 add-in

  4. #4
    Join Date
    Aug 2007
    Location
    Minneapolis
    Posts
    155

    Post Re: Update Combobox - Delegates

    The BackgroundWorker class works pretty slick. . .might just be what you need, here's a sample
    Code:
    private void button1_Click(object sender, System.EventArgs e)
    {
      using (BackgroundWorker worker = new BackgroundWorker())
      {
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        worker.RunWorkerAsync();
      }
    }
    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
      DataTable dt = new DataTable("Table1");
      dt.Columns.Add("Field1", typeof(int));
      dt.Columns.Add("Field2", typeof(string));
      dt.Rows.Add(new object[] { 1, "Value1" });
      dt.Rows.Add(new object[] { 2, "Value2" });
      e.Result = dt;
    }
    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      comboBox1.DataSource = (DataTable)e.Result;
      comboBox1.ValueMember = "Field1";
      comboBox1.DisplayMember = "Field2";
    }
    The worker_DoWork member executes on the background thread and the worker_RunWorkerCompleted member executes on the primary thread
    Last edited by trenches; September 9th, 2007 at 10:11 PM. Reason: code update

  5. #5
    Join Date
    Apr 2007
    Location
    Florida
    Posts
    403

    Re: Update Combobox - Delegates

    Got it with background worker, very very cool stuff thanks guys.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)