<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Tim Mackey's Weblog - .Net Compact</title>
    <link>http://tim.mackey.ie/</link>
    <description>mostly.Net</description>
    <language>en-ie</language>
    <copyright>Tim Mackey</copyright>
    <lastBuildDate>Wed, 26 May 2010 14:51:34 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>tim@mackey.ie</managingEditor>
    <webMaster>tim@mackey.ie</webMaster>
    <item>
      <trackback:ping>http://tim.mackey.ie/Trackback.aspx?guid=caab5837-eebf-428b-a239-a5b266046f57</trackback:ping>
      <pingback:server>http://tim.mackey.ie/pingback.aspx</pingback:server>
      <pingback:target>http://tim.mackey.ie/PermaLink,guid,caab5837-eebf-428b-a239-a5b266046f57.aspx</pingback:target>
      <dc:creator>Tim Mackey</dc:creator>
      <wfw:comment>http://tim.mackey.ie/CommentView,guid,caab5837-eebf-428b-a239-a5b266046f57.aspx</wfw:comment>
      <wfw:commentRss>http://tim.mackey.ie/SyndicationService.asmx/GetEntryCommentsRss?guid=caab5837-eebf-428b-a239-a5b266046f57</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">As any compact framework developer will
tell you, the out-of-the-box ListBox control is a bit crap because it doesn't support
horizontal scrolling.  what were they thinking??<br />
anyway, after several work-arounds to this problem, i finally realised that the treeview
control does support horizontal scrolling, and you can load up a treeview to look
just like a listbox, having all the nodes added at the top level, i.e. a "flat" treeview.<br />
the extra bonus with this approach is that Windows Mobile 6.5 has a brilliant touch
friendly Treeview control that you can finger-drag up and down and left and right
(at least the HTC HD2 has this, i can't vouch for other devices). 
<br /><br />
i've included a "Chooser" class i wrote to make user selections easy to code for. 
to use the class, use the following approach, the SelectedItem string is kept as a
static variable in the Form so you can close and dispose the form straight away, and
still catch the "return" value of the form. If you pass in the parameter to use Checkboxes,
you can access the CheckedItems static property which is a List&lt;string&gt;.<br /><pre>Chooser c = new Chooser("Select Item", new string[]{"Option 1", "Option 2", "Option 3"}, true, true); 
<br />
DialogResult d = c.ShowDialog();<br />
c.Dispose();<br />
if(d != DialogResult.Cancel)<br />
MessageBox.Show("You chose " + Chooser.SelectedItem);<br /></pre>here's the class then:<br /><pre>using System;<br />
using System.Collections.Generic;<br />
using System.ComponentModel;<br />
using System.Data;<br />
using System.Drawing;<br />
using System.Text;<br />
using System.Windows.Forms;<br />
using System.Threading;<br /><br />
namespace IbenzaMobileUtil<br />
{<br />
public partial class Chooser : Form<br />
{<br />
private MainMenu mainMenu1;<br />
private MenuItem mmOK;<br />
private MenuItem mmCancel;<br />
private Label lblCaption;<br />
public static string SelectedItem = null;<br />
public static List&lt;string&gt; CheckedItems = null;<br />
private TreeView treeView1;<br />
private bool selectInvokesClose;<br /><br /><br />
public Chooser()<br />
{<br />
InitializeComponent();<br />
}<br /><br />
private Chooser(string Caption, bool FullScreen, bool SelectInvokesClose)<br />
{<br />
InitializeComponent();<br />
CheckedItems = new List&lt;string&gt;();<br />
SelectedItem = null;<br />
this.selectInvokesClose = SelectInvokesClose;<br />
this.lblCaption.Text = Caption;<br />
this.mmOK.Enabled = false;<br /><br />
if (FullScreen)<br />
{<br />
this.WindowState = FormWindowState.Maximized;<br />
this.FormBorderStyle = FormBorderStyle.None;<br />
this.ControlBox = false;<br />
this.MinimizeBox = false;<br />
}<br />
}<br /><br />
public Chooser(string Caption, string[] Items, bool FullScreen, bool SelectInvokesClose)<br />
: this(Caption, FullScreen, SelectInvokesClose)<br />
{<br />
this.treeView1.BeginUpdate();<br />
foreach (string s in Items)<br />
this.treeView1.Nodes.Add(s);<br />
this.treeView1.EndUpdate();<br />
}<br /><br />
public Chooser(string Caption, string[] Items, bool FullScreen, bool CheckBoxes, bool
SelectInvokesClose, bool CheckAll)<br />
: this(Caption, Items, FullScreen, SelectInvokesClose)<br />
{<br />
this.treeView1.CheckBoxes = CheckBoxes;<br />
if (CheckBoxes &amp;&amp; CheckAll)<br />
foreach (TreeNode node in this.treeView1.Nodes)<br />
node.Checked = true;<br />
if(CheckBoxes)<br />
this.mmOK.Enabled = true; // don't require any user input<br />
}<br /><br />
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)<br />
{<br />
this.mmOK.Enabled = true;<br />
if (selectInvokesClose)<br />
this.mmOK_Click(sender, EventArgs.Empty);<br />
}<br /><br />
#region Windows Form Designer generated code<br /><br />
/// &lt;summary&gt;<br />
/// Required designer variable.<br />
/// &lt;/summary&gt;<br />
private System.ComponentModel.IContainer components = null;<br /><br />
/// &lt;summary&gt;<br />
/// Clean up any resources being used.<br />
/// &lt;/summary&gt;<br />
/// &lt;param name="disposing"&gt;true if managed resources should be disposed; otherwise,
false.&lt;/param&gt;<br />
protected override void Dispose(bool disposing)<br />
{<br />
if (disposing &amp;&amp; (components != null))<br />
{<br />
components.Dispose();<br />
}<br />
base.Dispose(disposing);<br />
}<br /><br /><br />
/// &lt;summary&gt;<br />
/// Required method for Designer support - do not modify<br />
/// the contents of this method with the code editor.<br />
/// &lt;/summary&gt;<br />
private void InitializeComponent()<br />
{<br />
this.mainMenu1 = new System.Windows.Forms.MainMenu();<br />
this.mmCancel = new System.Windows.Forms.MenuItem();<br />
this.mmOK = new System.Windows.Forms.MenuItem();<br />
this.lblCaption = new System.Windows.Forms.Label();<br />
this.treeView1 = new System.Windows.Forms.TreeView();<br />
this.SuspendLayout();<br />
// 
<br />
// mainMenu1<br />
// 
<br />
this.mainMenu1.MenuItems.Add(this.mmCancel);<br />
this.mainMenu1.MenuItems.Add(this.mmOK);<br />
// 
<br />
// mmCancel<br />
// 
<br />
this.mmCancel.Text = "Cancel";<br />
this.mmCancel.Click += new System.EventHandler(this.mmCancel_Click);<br />
// 
<br />
// mmOK<br />
// 
<br />
this.mmOK.Text = "OK";<br />
this.mmOK.Click += new System.EventHandler(this.mmOK_Click);<br />
// 
<br />
// lblCaption<br />
// 
<br />
this.lblCaption.Dock = System.Windows.Forms.DockStyle.Top;<br />
this.lblCaption.Font = new System.Drawing.Font("Tahoma", 10F, System.Drawing.FontStyle.Bold);<br />
this.lblCaption.Location = new System.Drawing.Point(0, 0);<br />
this.lblCaption.Name = "lblCaption";<br />
this.lblCaption.Size = new System.Drawing.Size(240, 27);<br />
this.lblCaption.Text = "...";<br />
// 
<br />
// treeView1<br />
// 
<br />
this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;<br />
this.treeView1.Location = new System.Drawing.Point(0, 27);<br />
this.treeView1.Name = "treeView1";<br />
this.treeView1.ShowLines = false;<br />
this.treeView1.ShowPlusMinus = false;<br />
this.treeView1.ShowRootLines = false;<br />
this.treeView1.Size = new System.Drawing.Size(240, 241);<br />
this.treeView1.TabIndex = 12;<br />
// 
<br />
// Chooser<br />
// 
<br />
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);<br />
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;<br />
this.AutoScroll = true;<br />
this.ClientSize = new System.Drawing.Size(240, 268);<br />
this.ControlBox = false;<br />
this.Controls.Add(this.treeView1);<br />
this.Controls.Add(this.lblCaption);<br />
this.KeyPreview = true;<br />
this.Menu = this.mainMenu1;<br />
this.MinimizeBox = false;<br />
this.Name = "Chooser";<br />
this.Text = "Choose Item";<br />
this.Load += new System.EventHandler(this.Chooser_Load);<br />
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Chooser_KeyDown);<br />
this.ResumeLayout(false);<br /><br />
}<br />
#endregion<br /><br />
private void Chooser_KeyDown(object sender, KeyEventArgs e)<br />
{<br />
if ((e.KeyCode == System.Windows.Forms.Keys.Enter))<br />
this.mmOK_Click(sender, EventArgs.Empty);<br />
}<br /><br />
private void mmOK_Click(object sender, EventArgs e)<br />
{<br />
if (this.treeView1.SelectedNode != null)<br />
Chooser.SelectedItem = this.treeView1.SelectedNode.Text;<br />
if (this.treeView1.CheckBoxes)<br />
foreach (TreeNode n in this.treeView1.Nodes)<br />
if (n.Checked)<br />
CheckedItems.Add(n.Text); 
<br /><br />
this.DialogResult = DialogResult.OK;<br />
this.Close();<br />
}<br /><br />
private void mmCancel_Click(object sender, EventArgs e)<br />
{<br />
this.DialogResult = DialogResult.Cancel;<br />
this.Close();<br />
}<br /><br />
private void Chooser_Load(object sender, EventArgs e)<br />
{<br />
this.treeView1.Focus();<br />
this.treeView1.SelectedNode = null;<br />
this.treeView1.AfterSelect += new TreeViewEventHandler(treeView1_AfterSelect);<br />
}<br />
}<br />
}<br /></pre><p></p><img width="0" height="0" src="http://tim.mackey.ie/aggbug.ashx?id=caab5837-eebf-428b-a239-a5b266046f57" /></body>
      <title>Compact Framework - Using the Treeview to replace the ListBox</title>
      <guid isPermaLink="false">http://tim.mackey.ie/PermaLink,guid,caab5837-eebf-428b-a239-a5b266046f57.aspx</guid>
      <link>http://tim.mackey.ie/CompactFrameworkUsingTheTreeviewToReplaceTheListBox.aspx</link>
      <pubDate>Wed, 26 May 2010 14:51:34 GMT</pubDate>
      <description>As any compact framework developer will tell you, the out-of-the-box ListBox control is a bit crap because it doesn't support horizontal scrolling.&amp;nbsp; what were they thinking??&lt;br&gt;
anyway, after several work-arounds to this problem, i finally realised that the treeview
control does support horizontal scrolling, and you can load up a treeview to look
just like a listbox, having all the nodes added at the top level, i.e. a "flat" treeview.&lt;br&gt;
the extra bonus with this approach is that Windows Mobile 6.5 has a brilliant touch
friendly Treeview control that you can finger-drag up and down and left and right
(at least the HTC HD2 has this, i can't vouch for other devices). 
&lt;br&gt;
&lt;br&gt;
i've included a "Chooser" class i wrote to make user selections easy to code for.&amp;nbsp;
to use the class, use the following approach, the SelectedItem string is kept as a
static variable in the Form so you can close and dispose the form straight away, and
still catch the "return" value of the form. If you pass in the parameter to use Checkboxes,
you can access the CheckedItems static property which is a List&amp;lt;string&amp;gt;.&lt;br&gt;
&lt;pre&gt;Chooser c = new Chooser("Select Item", new string[]{"Option 1", "Option 2", "Option 3"}, true, true); 
&lt;br&gt;
DialogResult d = c.ShowDialog();&lt;br&gt;
c.Dispose();&lt;br&gt;
if(d != DialogResult.Cancel)&lt;br&gt;
MessageBox.Show("You chose " + Chooser.SelectedItem);&lt;br&gt;
&lt;/pre&gt;here's the class then:&lt;br&gt;
&lt;pre&gt;using System;&lt;br&gt;
using System.Collections.Generic;&lt;br&gt;
using System.ComponentModel;&lt;br&gt;
using System.Data;&lt;br&gt;
using System.Drawing;&lt;br&gt;
using System.Text;&lt;br&gt;
using System.Windows.Forms;&lt;br&gt;
using System.Threading;&lt;br&gt;
&lt;br&gt;
namespace IbenzaMobileUtil&lt;br&gt;
{&lt;br&gt;
public partial class Chooser : Form&lt;br&gt;
{&lt;br&gt;
private MainMenu mainMenu1;&lt;br&gt;
private MenuItem mmOK;&lt;br&gt;
private MenuItem mmCancel;&lt;br&gt;
private Label lblCaption;&lt;br&gt;
public static string SelectedItem = null;&lt;br&gt;
public static List&amp;lt;string&amp;gt; CheckedItems = null;&lt;br&gt;
private TreeView treeView1;&lt;br&gt;
private bool selectInvokesClose;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
public Chooser()&lt;br&gt;
{&lt;br&gt;
InitializeComponent();&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private Chooser(string Caption, bool FullScreen, bool SelectInvokesClose)&lt;br&gt;
{&lt;br&gt;
InitializeComponent();&lt;br&gt;
CheckedItems = new List&amp;lt;string&amp;gt;();&lt;br&gt;
SelectedItem = null;&lt;br&gt;
this.selectInvokesClose = SelectInvokesClose;&lt;br&gt;
this.lblCaption.Text = Caption;&lt;br&gt;
this.mmOK.Enabled = false;&lt;br&gt;
&lt;br&gt;
if (FullScreen)&lt;br&gt;
{&lt;br&gt;
this.WindowState = FormWindowState.Maximized;&lt;br&gt;
this.FormBorderStyle = FormBorderStyle.None;&lt;br&gt;
this.ControlBox = false;&lt;br&gt;
this.MinimizeBox = false;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
public Chooser(string Caption, string[] Items, bool FullScreen, bool SelectInvokesClose)&lt;br&gt;
: this(Caption, FullScreen, SelectInvokesClose)&lt;br&gt;
{&lt;br&gt;
this.treeView1.BeginUpdate();&lt;br&gt;
foreach (string s in Items)&lt;br&gt;
this.treeView1.Nodes.Add(s);&lt;br&gt;
this.treeView1.EndUpdate();&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
public Chooser(string Caption, string[] Items, bool FullScreen, bool CheckBoxes, bool
SelectInvokesClose, bool CheckAll)&lt;br&gt;
: this(Caption, Items, FullScreen, SelectInvokesClose)&lt;br&gt;
{&lt;br&gt;
this.treeView1.CheckBoxes = CheckBoxes;&lt;br&gt;
if (CheckBoxes &amp;amp;&amp;amp; CheckAll)&lt;br&gt;
foreach (TreeNode node in this.treeView1.Nodes)&lt;br&gt;
node.Checked = true;&lt;br&gt;
if(CheckBoxes)&lt;br&gt;
this.mmOK.Enabled = true; // don't require any user input&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)&lt;br&gt;
{&lt;br&gt;
this.mmOK.Enabled = true;&lt;br&gt;
if (selectInvokesClose)&lt;br&gt;
this.mmOK_Click(sender, EventArgs.Empty);&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
#region Windows Form Designer generated code&lt;br&gt;
&lt;br&gt;
/// &amp;lt;summary&amp;gt;&lt;br&gt;
/// Required designer variable.&lt;br&gt;
/// &amp;lt;/summary&amp;gt;&lt;br&gt;
private System.ComponentModel.IContainer components = null;&lt;br&gt;
&lt;br&gt;
/// &amp;lt;summary&amp;gt;&lt;br&gt;
/// Clean up any resources being used.&lt;br&gt;
/// &amp;lt;/summary&amp;gt;&lt;br&gt;
/// &amp;lt;param name="disposing"&amp;gt;true if managed resources should be disposed; otherwise,
false.&amp;lt;/param&amp;gt;&lt;br&gt;
protected override void Dispose(bool disposing)&lt;br&gt;
{&lt;br&gt;
if (disposing &amp;amp;&amp;amp; (components != null))&lt;br&gt;
{&lt;br&gt;
components.Dispose();&lt;br&gt;
}&lt;br&gt;
base.Dispose(disposing);&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
/// &amp;lt;summary&amp;gt;&lt;br&gt;
/// Required method for Designer support - do not modify&lt;br&gt;
/// the contents of this method with the code editor.&lt;br&gt;
/// &amp;lt;/summary&amp;gt;&lt;br&gt;
private void InitializeComponent()&lt;br&gt;
{&lt;br&gt;
this.mainMenu1 = new System.Windows.Forms.MainMenu();&lt;br&gt;
this.mmCancel = new System.Windows.Forms.MenuItem();&lt;br&gt;
this.mmOK = new System.Windows.Forms.MenuItem();&lt;br&gt;
this.lblCaption = new System.Windows.Forms.Label();&lt;br&gt;
this.treeView1 = new System.Windows.Forms.TreeView();&lt;br&gt;
this.SuspendLayout();&lt;br&gt;
// 
&lt;br&gt;
// mainMenu1&lt;br&gt;
// 
&lt;br&gt;
this.mainMenu1.MenuItems.Add(this.mmCancel);&lt;br&gt;
this.mainMenu1.MenuItems.Add(this.mmOK);&lt;br&gt;
// 
&lt;br&gt;
// mmCancel&lt;br&gt;
// 
&lt;br&gt;
this.mmCancel.Text = "Cancel";&lt;br&gt;
this.mmCancel.Click += new System.EventHandler(this.mmCancel_Click);&lt;br&gt;
// 
&lt;br&gt;
// mmOK&lt;br&gt;
// 
&lt;br&gt;
this.mmOK.Text = "OK";&lt;br&gt;
this.mmOK.Click += new System.EventHandler(this.mmOK_Click);&lt;br&gt;
// 
&lt;br&gt;
// lblCaption&lt;br&gt;
// 
&lt;br&gt;
this.lblCaption.Dock = System.Windows.Forms.DockStyle.Top;&lt;br&gt;
this.lblCaption.Font = new System.Drawing.Font("Tahoma", 10F, System.Drawing.FontStyle.Bold);&lt;br&gt;
this.lblCaption.Location = new System.Drawing.Point(0, 0);&lt;br&gt;
this.lblCaption.Name = "lblCaption";&lt;br&gt;
this.lblCaption.Size = new System.Drawing.Size(240, 27);&lt;br&gt;
this.lblCaption.Text = "...";&lt;br&gt;
// 
&lt;br&gt;
// treeView1&lt;br&gt;
// 
&lt;br&gt;
this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;&lt;br&gt;
this.treeView1.Location = new System.Drawing.Point(0, 27);&lt;br&gt;
this.treeView1.Name = "treeView1";&lt;br&gt;
this.treeView1.ShowLines = false;&lt;br&gt;
this.treeView1.ShowPlusMinus = false;&lt;br&gt;
this.treeView1.ShowRootLines = false;&lt;br&gt;
this.treeView1.Size = new System.Drawing.Size(240, 241);&lt;br&gt;
this.treeView1.TabIndex = 12;&lt;br&gt;
// 
&lt;br&gt;
// Chooser&lt;br&gt;
// 
&lt;br&gt;
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);&lt;br&gt;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;&lt;br&gt;
this.AutoScroll = true;&lt;br&gt;
this.ClientSize = new System.Drawing.Size(240, 268);&lt;br&gt;
this.ControlBox = false;&lt;br&gt;
this.Controls.Add(this.treeView1);&lt;br&gt;
this.Controls.Add(this.lblCaption);&lt;br&gt;
this.KeyPreview = true;&lt;br&gt;
this.Menu = this.mainMenu1;&lt;br&gt;
this.MinimizeBox = false;&lt;br&gt;
this.Name = "Chooser";&lt;br&gt;
this.Text = "Choose Item";&lt;br&gt;
this.Load += new System.EventHandler(this.Chooser_Load);&lt;br&gt;
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Chooser_KeyDown);&lt;br&gt;
this.ResumeLayout(false);&lt;br&gt;
&lt;br&gt;
}&lt;br&gt;
#endregion&lt;br&gt;
&lt;br&gt;
private void Chooser_KeyDown(object sender, KeyEventArgs e)&lt;br&gt;
{&lt;br&gt;
if ((e.KeyCode == System.Windows.Forms.Keys.Enter))&lt;br&gt;
this.mmOK_Click(sender, EventArgs.Empty);&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private void mmOK_Click(object sender, EventArgs e)&lt;br&gt;
{&lt;br&gt;
if (this.treeView1.SelectedNode != null)&lt;br&gt;
Chooser.SelectedItem = this.treeView1.SelectedNode.Text;&lt;br&gt;
if (this.treeView1.CheckBoxes)&lt;br&gt;
foreach (TreeNode n in this.treeView1.Nodes)&lt;br&gt;
if (n.Checked)&lt;br&gt;
CheckedItems.Add(n.Text); 
&lt;br&gt;
&lt;br&gt;
this.DialogResult = DialogResult.OK;&lt;br&gt;
this.Close();&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private void mmCancel_Click(object sender, EventArgs e)&lt;br&gt;
{&lt;br&gt;
this.DialogResult = DialogResult.Cancel;&lt;br&gt;
this.Close();&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private void Chooser_Load(object sender, EventArgs e)&lt;br&gt;
{&lt;br&gt;
this.treeView1.Focus();&lt;br&gt;
this.treeView1.SelectedNode = null;&lt;br&gt;
this.treeView1.AfterSelect += new TreeViewEventHandler(treeView1_AfterSelect);&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://tim.mackey.ie/aggbug.ashx?id=caab5837-eebf-428b-a239-a5b266046f57" /&gt;</description>
      <comments>http://tim.mackey.ie/CommentView,guid,caab5837-eebf-428b-a239-a5b266046f57.aspx</comments>
      <category>.Net Compact</category>
    </item>
    <item>
      <trackback:ping>http://tim.mackey.ie/Trackback.aspx?guid=8abd58fe-f5fb-45e9-a079-280cdb67b131</trackback:ping>
      <pingback:server>http://tim.mackey.ie/pingback.aspx</pingback:server>
      <pingback:target>http://tim.mackey.ie/PermaLink,guid,8abd58fe-f5fb-45e9-a079-280cdb67b131.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://tim.mackey.ie/CommentView,guid,8abd58fe-f5fb-45e9-a079-280cdb67b131.aspx</wfw:comment>
      <wfw:commentRss>http://tim.mackey.ie/SyndicationService.asmx/GetEntryCommentsRss?guid=8abd58fe-f5fb-45e9-a079-280cdb67b131</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">what a frustrating problem this was. 
delegates weren't support in CF1, but now we have CF2 and according to <a href="http://msdn2.microsoft.com/en-us/library/Aa446574.aspx#whats_new_netcf2_topic6">microsoft</a>:<br /><blockquote><p><i>The .NET Compact Framework 2.0 now supports asynchronous execution
of a delegate on a user interface thread. Unlike the .NET Compact Framework 1.0
that supports only the <b>Control.Invoke</b> method (which synchronously executes
a delegate on a control's owning thread), the .NET Compact Framework 2.0
provides <b>Control.BeginInvoke</b> that asynchronously executes a delegate on the
control's owning thread. The <b>Control.EndInvoke</b> method is also provided. When
called, the <b>EndInvoke</b> method returns the results of an asynchronous operation.</i></p></blockquote><p></p>
This is great but it's easily assumed that delegates are fully supported now in CF2,
but no such luck.  they don't say that calling BeginInvoke on a delegate will
cause your application to crash (with a NotSupportedException) even though it will
compile in visual studio without warning or error.  there is an excellent (if
lengthy) discussion on the matter on this <a href="http://groups.google.com/group/microsoft.public.dotnet.framework.compactframework/browse_thread/thread/8d1dcae717897416/17e2ca0cd8937c1b?lnk=st&amp;q=CF+BeginInvoke+delegate&amp;rnum=4#17e2ca0cd8937c1b">newsgroup
post</a>.  the long and short of it is that you should use the ThreadPool class
instead of using delegates to fire off worker threads.  You can still use delegates
to send a function back to the UI thread just like in winforms.  Notice in the
code below that the method signature of the function you are starting the thread on,
requires a single 'object' parameter.<br /><pre>using System.Threading;<br /><br />
private void Button_Click(etc)<br />
{<br />
ThreadPool.QueueUserWorkItem(new WaitCallback(this.DoSomeWork));<br />
}<br /><br />
private void DoSomeWork(object o)<br />
{<br />
...<br />
}<br /></pre><img width="0" height="0" src="http://tim.mackey.ie/aggbug.ashx?id=8abd58fe-f5fb-45e9-a079-280cdb67b131" /></body>
      <title>MultiThreading In CF2 with Delegates</title>
      <guid isPermaLink="false">http://tim.mackey.ie/PermaLink,guid,8abd58fe-f5fb-45e9-a079-280cdb67b131.aspx</guid>
      <link>http://tim.mackey.ie/MultiThreadingInCF2WithDelegates.aspx</link>
      <pubDate>Tue, 09 Oct 2007 14:00:03 GMT</pubDate>
      <description>what a frustrating problem this was.&amp;nbsp; delegates weren't support in CF1, but now we have CF2 and according to &lt;a href="http://msdn2.microsoft.com/en-us/library/Aa446574.aspx#whats_new_netcf2_topic6"&gt;microsoft&lt;/a&gt;:&lt;br&gt;
&lt;blockquote&gt;
&lt;p&gt;
&lt;i&gt;The .NET&amp;nbsp;Compact&amp;nbsp;Framework&amp;nbsp;2.0 now supports asynchronous execution
of a delegate on a user interface thread. Unlike the .NET&amp;nbsp;Compact&amp;nbsp;Framework&amp;nbsp;1.0
that supports only the &lt;b&gt;Control.Invoke&lt;/b&gt; method (which synchronously executes
a delegate on a control's owning thread), the .NET&amp;nbsp;Compact&amp;nbsp;Framework&amp;nbsp;2.0
provides &lt;b&gt;Control.BeginInvoke&lt;/b&gt; that asynchronously executes a delegate on the
control's owning thread. The &lt;b&gt;Control.EndInvoke&lt;/b&gt; method is also provided. When
called, the &lt;b&gt;EndInvoke&lt;/b&gt; method returns the results of an asynchronous operation.&lt;/i&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;/p&gt;
This is great but it's easily assumed that delegates are fully supported now in CF2,
but no such luck.&amp;nbsp; they don't say that calling BeginInvoke on a delegate will
cause your application to crash (with a NotSupportedException) even though it will
compile in visual studio without warning or error.&amp;nbsp; there is an excellent (if
lengthy) discussion on the matter on this &lt;a href="http://groups.google.com/group/microsoft.public.dotnet.framework.compactframework/browse_thread/thread/8d1dcae717897416/17e2ca0cd8937c1b?lnk=st&amp;amp;q=CF+BeginInvoke+delegate&amp;amp;rnum=4#17e2ca0cd8937c1b"&gt;newsgroup
post&lt;/a&gt;.&amp;nbsp; the long and short of it is that you should use the ThreadPool class
instead of using delegates to fire off worker threads.&amp;nbsp; You can still use delegates
to send a function back to the UI thread just like in winforms.&amp;nbsp; Notice in the
code below that the method signature of the function you are starting the thread on,
requires a single 'object' parameter.&lt;br&gt;
&lt;pre&gt;using System.Threading;&lt;br&gt;
&lt;br&gt;
private void Button_Click(etc)&lt;br&gt;
{&lt;br&gt;
ThreadPool.QueueUserWorkItem(new WaitCallback(this.DoSomeWork));&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private void DoSomeWork(object o)&lt;br&gt;
{&lt;br&gt;
...&lt;br&gt;
}&lt;br&gt;
&lt;/pre&gt;&lt;img width="0" height="0" src="http://tim.mackey.ie/aggbug.ashx?id=8abd58fe-f5fb-45e9-a079-280cdb67b131" /&gt;</description>
      <comments>http://tim.mackey.ie/CommentView,guid,8abd58fe-f5fb-45e9-a079-280cdb67b131.aspx</comments>
      <category>.Net Compact</category>
    </item>
    <item>
      <trackback:ping>http://tim.mackey.ie/Trackback.aspx?guid=d7c7e858-3da0-4bb2-a12b-aa0cf254462e</trackback:ping>
      <pingback:server>http://tim.mackey.ie/pingback.aspx</pingback:server>
      <pingback:target>http://tim.mackey.ie/PermaLink,guid,d7c7e858-3da0-4bb2-a12b-aa0cf254462e.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://tim.mackey.ie/CommentView,guid,d7c7e858-3da0-4bb2-a12b-aa0cf254462e.aspx</wfw:comment>
      <wfw:commentRss>http://tim.mackey.ie/SyndicationService.asmx/GetEntryCommentsRss?guid=d7c7e858-3da0-4bb2-a12b-aa0cf254462e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">big bug in ComboBox control here: <a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;327244">http://support.microsoft.com/default.aspx?scid=kb;en-us;327244</a><br />
you have to set the SelectedIndex to -1 twice in a row if you want it to take effect!<br />
i came across this in a compact framework app, but it looks like it applies to win-forms
as well.<br /><p></p><img width="0" height="0" src="http://tim.mackey.ie/aggbug.ashx?id=d7c7e858-3da0-4bb2-a12b-aa0cf254462e" /></body>
      <title>Bug in ComboBox SelectedIndex</title>
      <guid isPermaLink="false">http://tim.mackey.ie/PermaLink,guid,d7c7e858-3da0-4bb2-a12b-aa0cf254462e.aspx</guid>
      <link>http://tim.mackey.ie/BugInComboBoxSelectedIndex.aspx</link>
      <pubDate>Tue, 02 Oct 2007 16:17:18 GMT</pubDate>
      <description>big bug in ComboBox control here: &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;327244"&gt;http://support.microsoft.com/default.aspx?scid=kb;en-us;327244&lt;/a&gt;
&lt;br&gt;
you have to set the SelectedIndex to -1 twice in a row if you want it to take effect!&lt;br&gt;
i came across this in a compact framework app, but it looks like it applies to win-forms
as well.&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://tim.mackey.ie/aggbug.ashx?id=d7c7e858-3da0-4bb2-a12b-aa0cf254462e" /&gt;</description>
      <comments>http://tim.mackey.ie/CommentView,guid,d7c7e858-3da0-4bb2-a12b-aa0cf254462e.aspx</comments>
      <category>.Net Compact</category>
      <category>.Net Windows Forms</category>
    </item>
  </channel>
</rss>