<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-10549483</id><updated>2011-11-27T15:34:51.038-08:00</updated><title type='text'>.NET Dutch</title><subtitle type='html'>A blogger about .Net technology</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>56</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-10549483.post-2084416104334974857</id><published>2009-01-22T23:22:00.000-08:00</published><updated>2009-01-23T08:20:57.172-08:00</updated><title type='text'>Back online</title><content type='html'>It's been a long long time I have been posting. It's not that time stood still, but I wondered what I or why I should write.&lt;br /&gt;&lt;br /&gt;At the moment web 2.0 is hot. We are trying to understand a new platform called cloud computing. Software is becoming more a service (SaaS). With all these inventions, we have to step on this train. So it's time to I know what they really talk about.&lt;br /&gt;&lt;br /&gt;Is there someone who know's what web 2.0 is? &lt;a href="http://en.wikipedia.org/wiki/Web_2.0"&gt; Read it at wikipedia&lt;/a&gt;. So is it clear for you now? Not yet is it? Is is just a summation of what has been achieved the last year at internet? Yes that is it: RIA's, Social network sites, Interactive websites and services. A lot of new technologies combined fall under web 2.0: AJAX, Silverlight, Web services. A lot of public sites or services that are widely and common used: Google Search, Google maps, Google Docs, youtube, LinkedIn, Hyves.&lt;br /&gt;&lt;br /&gt;Unfortunately the new &lt;a href="http://nl.wikipedia.org/wiki/Internet_Protocol_Version_6"&gt;IPV6 protocol&lt;/a&gt; is not part of Web 2.0. &lt;br /&gt;&lt;br /&gt;Is there someone who know's what is cloud computing? This video gives a clear explanation of it. &lt;br /&gt;&lt;object width="340" height="285"&gt;&lt;param name="movie" value="http://www.youtube.com/v/QJncFirhjPg&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0&amp;amp;color1=0x2b405b&amp;amp;color2=0x6b8ab6&amp;amp;border=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/QJncFirhjPg&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0&amp;amp;color1=0x2b405b&amp;amp;color2=0x6b8ab6&amp;amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="340" height="285"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;It's certainly more than hiring capacity at a hosting party. Microsoft is developing Windows Azure (cloud computing). &lt;a href="http://news.cnet.com/microsoft-launches-windows-azure/"&gt; read more...&lt;/a&gt;. It's a kind of platform where you can deploy your services. May be you think that Microsoft invented it. But that's not true. Amazon has already a similar platform live. &lt;a href="http://aws.amazon.com/ec2/"&gt;read more...&lt;/a&gt;. Also Google and IBM cooperate and deliver cloud computing services. &lt;a href="http://www.technologyreview.com/biztech/19785/?a=f"&gt;read more...&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A good example of a cloud computing product is &lt;a href="http://www.outlookcloud.com/"&gt; outlook cloud&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;More on cloud computing (cloud applications) &lt;br /&gt;&lt;a href="http://news.zdnet.com/2422-19178_22-246700.html"&gt;ZDNet video&lt;/a&gt;&lt;br /&gt;&lt;a href="http://news.bbc.co.uk/2/hi/programmes/click_online/7464153.stm"&gt;Cloud applications&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-2084416104334974857?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/2084416104334974857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=2084416104334974857&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/2084416104334974857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/2084416104334974857'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2009/01/back-online.html' title='Back online'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-1814136681429497627</id><published>2007-03-02T03:27:00.000-08:00</published><updated>2007-03-02T04:05:59.539-08:00</updated><title type='text'>Reflection overload</title><content type='html'>More often I am using Reflection. I translate DataSource objects to collections, DataTable object etc. The underlying reason is that I used datasource objects in controls. And most controls have a display and a ValueMember. The ComboBox Column in a DataGridView controls seems to be very slow. I think it Microsoft uses the IList interface for all DataSource objects. In case of a ComboBoxColumn an dictionary object would be more approriate. A dictionary object works with a hash key, a kind of database index. Only it has not a Ilist interface. The dictionary gives a performance boost. But how do I translate a IList DataSource to a non IList DataSource and use it?&lt;br /&gt;&lt;br /&gt;See here a possible solution&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public static Dictionary&lt;string,string&gt; DataSourceToDictionary(object dataSource, string valueMember, string displayMember)&lt;br /&gt;{&lt;br /&gt;IList list = dataSource as IList;&lt;br /&gt;Dictionary&lt;string,&gt; listLookup = new Dictionary&lt;string,&gt;();&lt;br /&gt;if (list != null &amp;&amp;amp; list.Count &gt; 0)&lt;br /&gt;{&lt;br /&gt;PropertyInfo valueMemberInfo = dataSource.GetType().GetGenericArguments()[0].GetProperty(valueMember);&lt;br /&gt;PropertyInfo displayMemberInfo = dataSource.GetType().GetGenericArguments()[0].GetProperty(displayMember);&lt;br /&gt;foreach (object item in list)&lt;br /&gt;{&lt;br /&gt;listLookup.Add(valueMemberInfo.GetValue(item, null).ToString(), displayMemberInfo.GetValue(item, null).ToString());&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;return listLookup;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The dictionary is of template types: string, string. You could easily change this in Dictionary&lt;object,&gt;. But because, I am changing values from int to string in the DataGridView control I have chosen otherwise. Also Dictionary&lt;object,object&gt; is possible and overidde the ToString() of the second generics Template to get the DisplayMember show the right value.&lt;br /&gt;&lt;br /&gt;In the DataGridView control, I can now use an ordinary TextBoxColumn. The look up processing is already done before setting the DataSource property. I converted the DataSource to a DataTable object and applied the reference data to it.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public static DataTable ToDataTable(IList items, Dictionary&lt;string,&gt; referenceColumns)&lt;br /&gt;{&lt;br /&gt;if (items == null  referenceColumns == null)&lt;br /&gt;{&lt;br /&gt;return null;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;DataTable dt = new DataTable();&lt;br /&gt;&lt;br /&gt;//Retrieve list item properties&lt;br /&gt;Type listType = items.GetType();&lt;br /&gt;Type itemType=null;&lt;br /&gt;if (listType.IsGenericType)&lt;br /&gt;{&lt;br /&gt;itemType = listType.GetGenericArguments()[0];&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;itemType = listType.GetElementType();&lt;br /&gt;}&lt;br /&gt;PropertyInfo[] props = itemType.GetProperties();&lt;br /&gt;&lt;br /&gt;//Loop properties and add as columns to the datatable&lt;br /&gt;foreach (PropertyInfo prop in props)&lt;br /&gt;{&lt;br /&gt;DataColumn col = new DataColumn(prop.Name);&lt;br /&gt;if (prop.PropertyType.IsPrimitive &amp;&amp;amp; !referenceColumns.ContainsKey(col.ColumnName))&lt;br /&gt;{&lt;br /&gt;col.DataType = prop.PropertyType;&lt;br /&gt;}&lt;br /&gt;dt.Columns.Add(col);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Loop al datasource rows and&lt;br /&gt;//apply the values from the IList of the datasource object&lt;br /&gt;//to the DataTable object&lt;br /&gt;foreach (object item in items)&lt;br /&gt;{&lt;br /&gt;DataRow dr = dt.NewRow();&lt;br /&gt;foreach (PropertyInfo prop in props)&lt;br /&gt;{&lt;br /&gt;dr[prop.Name] = prop.GetValue(item, null);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;dt.Rows.Add(dr);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Apply reference columns&lt;br /&gt;            foreach (string key in referenceColumns.Keys)&lt;br /&gt;            {&lt;br /&gt;                DataSourceLookupObject dataSourceLookupObject = referenceColumns[key];&lt;br /&gt;                if (!dt.Columns.Contains(key))&lt;br /&gt;                {&lt;br /&gt;                    PropertyInfo prop = itemType.GetProperty(dataSourceLookupObject.ColumnName);&lt;br /&gt;                    dt.Columns.Add(key);&lt;br /&gt;                    for (int rowIndex=0;rowIndex &lt; items.Count;rowIndex++)&lt;br /&gt;                    {&lt;br /&gt;                        dt.Rows[rowIndex][key] = prop.GetValue(items[rowIndex], null);&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            return dt;&lt;br /&gt;        }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Some developers complain about the performance of the DataGridView. Is it maybe the slow painting mechanism? There are a lot of tips to improve the performance of the DataGridView: &lt;a href="http://msdn2.microsoft.com/en-us/library/ms171621.aspx"&gt;Performance Tuning in the Windows Forms DataGridView Control&lt;/a&gt;. &lt;br /&gt;My tip is you can achieve performance boost mostly more simple. The key is processing during initializing of the control instead of during the user interphase processing phase. A good start is half the work. And the painting? It is not as bad as it seems to be.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-1814136681429497627?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/1814136681429497627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=1814136681429497627&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/1814136681429497627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/1814136681429497627'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2007/03/reflection-overload.html' title='Reflection overload'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-117032710533978220</id><published>2007-02-01T02:42:00.000-08:00</published><updated>2007-02-01T02:51:45.346-08:00</updated><title type='text'>Yet another Nullable DateTimePicker</title><content type='html'>I was looking for a nullable datetime picker that supported the DateTime? type. I found a good one at &lt;a href="http://www.grazioli.ch/blog/"&gt;Claudio's blog, at 25 April&lt;/a&gt;. This is just what I was looking for.&lt;br /&gt;&lt;br /&gt;I added another feature to set the BackColor of the picker. The background have to be set in the WndProc as well (hmm).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;protected override void WndProc(ref Message m)&lt;br /&gt;{&lt;br /&gt;// Check to see if message being send is WM_ERASEBKGND.&lt;br /&gt;// The hex value of this message is hex 14.&lt;br /&gt;// This message is sent when the background of the&lt;br /&gt;// object needs to be erased. In our case though, instead of&lt;br /&gt;// erasing it, we will paint a rectangle over it&lt;br /&gt;if (m.Msg == 0x14 &amp;&amp;amp; Enabled) // Then ' WM_ERASEBKGND&lt;br /&gt;{&lt;br /&gt;using (Graphics g = Graphics.FromHdc(m.WParam))&lt;br /&gt;{&lt;br /&gt;g.FillRectangle(new SolidBrush(BackColor), ClientRectangle);&lt;br /&gt;}&lt;br /&gt;return;&lt;br /&gt;}&lt;br /&gt;if (m.Msg == 0x4e) // WM_NOTIFY&lt;br /&gt;{&lt;br /&gt;NMHDR nm = (NMHDR) m.GetLParam(typeof (NMHDR));&lt;br /&gt;if (nm.Code == -746  nm.Code == -722) // DTN_CLOSEUP  DTN_?&lt;br /&gt;if (isNull)&lt;br /&gt;{&lt;br /&gt;SetToDateTimeValue();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;base.WndProc(ref m);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If you are interested, this is the full source. I have made some other changes as well. The delete key will erase the date value. I added that, if you type a key on a null date, the today value will be set. This makes it possible to edit the value of the textbox again.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.ComponentModel;&lt;br /&gt;using System.Drawing;&lt;br /&gt;using System.Globalization;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Threading;&lt;br /&gt;using System.Windows.Forms;&lt;br /&gt;&lt;br /&gt;namespace XXX.WinControls&lt;br /&gt;{&lt;br /&gt;public class DatePicker : DateTimePicker&lt;br /&gt;{&lt;br /&gt;#region member variables&lt;br /&gt;&lt;br /&gt;[StructLayout(LayoutKind.Sequential)]&lt;br /&gt;private struct NMHDR&lt;br /&gt;{&lt;br /&gt;public IntPtr HwndFrom;&lt;br /&gt;public int IdFrom;&lt;br /&gt;public int Code;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// true, when no date shall be displayed (empty DateTimePicker)&lt;br /&gt;private bool isNull;&lt;br /&gt;&lt;br /&gt;// If _isNull = true, this value is shown in the DTP&lt;br /&gt;private string nullValueText = "(none)";&lt;br /&gt;private string customFormat;&lt;br /&gt;private DateTimePickerFormat format;&lt;br /&gt;private string formatAsString;&lt;br /&gt;&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;[Browsable(true),DesignerSerializationVisibility(DesignerSerializationVisibility.Visible) ]&lt;br /&gt;[Category("Appearance"),Description("Gets or sets the BackColor") ]&lt;br /&gt;public override Color BackColor&lt;br /&gt;{&lt;br /&gt;get&lt;br /&gt;{&lt;br /&gt;return base.BackColor;&lt;br /&gt;}&lt;br /&gt;set&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;base.BackColor = value;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[Category("Appearance"), Description("Sets or gets the Null value text"),DefaultValue("(None)") ]&lt;br /&gt;public String NullValueText&lt;br /&gt;{&lt;br /&gt;get { return nullValueText; }&lt;br /&gt;set { nullValueText = value; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public new String CustomFormat&lt;br /&gt;{&lt;br /&gt;get { return customFormat; }&lt;br /&gt;set&lt;br /&gt;{&lt;br /&gt;customFormat = value;&lt;br /&gt;SetFormat();&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public new DateTimePickerFormat Format&lt;br /&gt;{&lt;br /&gt;get { return format; }&lt;br /&gt;set&lt;br /&gt;{&lt;br /&gt;format = value;&lt;br /&gt;SetFormat();&lt;br /&gt;Invalidate();&lt;br /&gt;OnFormatChanged(EventArgs.Empty);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[Category("Data"),Browsable(true), Description("Sets or gets the value "),Bindable(true)]&lt;br /&gt;public new DateTime? Value&lt;br /&gt;{&lt;br /&gt;get&lt;br /&gt;{&lt;br /&gt;if (isNull)&lt;br /&gt;{&lt;br /&gt;return null;&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;return base.Value;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;set&lt;br /&gt;{&lt;br /&gt;if (value.HasValue)&lt;br /&gt;{&lt;br /&gt;base.Value = value.Value;&lt;br /&gt;SetToDateTimeValue();&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;isNull = true;&lt;br /&gt;SetToNullValue();&lt;br /&gt;Invalidate();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private string FormatAsString&lt;br /&gt;{&lt;br /&gt;get { return formatAsString; }&lt;br /&gt;set&lt;br /&gt;{&lt;br /&gt;formatAsString = value;&lt;br /&gt;base.CustomFormat = value;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected override void WndProc(ref Message m)&lt;br /&gt;{&lt;br /&gt;// Check to see if message being send is WM_ERASEBKGND.&lt;br /&gt;// The hex value of this message is hex 14.&lt;br /&gt;// This message is sent when the background of the&lt;br /&gt;// object needs to be erased. In our case though, instead of&lt;br /&gt;// erasing it, we will paint a rectangle over it&lt;br /&gt;if (m.Msg == 0x14 &amp;&amp;amp; Enabled) // Then ' WM_ERASEBKGND&lt;br /&gt;{&lt;br /&gt;using (Graphics g = Graphics.FromHdc(m.WParam))&lt;br /&gt;{&lt;br /&gt;g.FillRectangle(new SolidBrush(BackColor), ClientRectangle);&lt;br /&gt;}&lt;br /&gt;return;&lt;br /&gt;}&lt;br /&gt;if (m.Msg == 0x4e) // WM_NOTIFY&lt;br /&gt;{&lt;br /&gt;NMHDR nm = (NMHDR) m.GetLParam(typeof (NMHDR));&lt;br /&gt;if (nm.Code == -746  nm.Code == -722) // DTN_CLOSEUP  DTN_?&lt;br /&gt;if (isNull)&lt;br /&gt;{&lt;br /&gt;SetToDateTimeValue();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;base.WndProc(ref m);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public DatePicker()&lt;br /&gt;{&lt;br /&gt;base.Format = DateTimePickerFormat.Custom;&lt;br /&gt;this.Format = DateTimePickerFormat.Short;&lt;br /&gt;Value = null;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private void SetFormat()&lt;br /&gt;{&lt;br /&gt;CultureInfo ci = Thread.CurrentThread.CurrentUICulture;&lt;br /&gt;DateTimeFormatInfo dtf = ci.DateTimeFormat;&lt;br /&gt;switch (format)&lt;br /&gt;{&lt;br /&gt;case DateTimePickerFormat.Long:&lt;br /&gt;FormatAsString = dtf.LongDatePattern;&lt;br /&gt;break;&lt;br /&gt;case DateTimePickerFormat.Short:&lt;br /&gt;FormatAsString = dtf.ShortDatePattern;&lt;br /&gt;break;&lt;br /&gt;case DateTimePickerFormat.Time:&lt;br /&gt;FormatAsString = dtf.ShortTimePattern;&lt;br /&gt;break;&lt;br /&gt;case DateTimePickerFormat.Custom:&lt;br /&gt;FormatAsString = this.CustomFormat;&lt;br /&gt;break;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;private void SetToDateTimeValue()&lt;br /&gt;{&lt;br /&gt;if (isNull)&lt;br /&gt;{&lt;br /&gt;SetFormat();&lt;br /&gt;isNull = false;&lt;br /&gt;//base.OnValueChanged(new EventArgs());&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private void SetToNullValue()&lt;br /&gt;{&lt;br /&gt;isNull = true;&lt;br /&gt;base.CustomFormat = String.IsNullOrEmpty(nullValueText) ? " " : "'" + NullValueText + "'";&lt;br /&gt;}&lt;br /&gt;/*&lt;br /&gt;protected override void OnCloseUp(EventArgs e)&lt;br /&gt;{&lt;br /&gt;if (Control.MouseButtons == MouseButtons.None &amp;&amp;amp; isNull)&lt;br /&gt;{&lt;br /&gt;SetToDateTimeValue();&lt;br /&gt;}&lt;br /&gt;base.OnCloseUp(e);&lt;br /&gt;}*/&lt;br /&gt;&lt;br /&gt;protected override void OnKeyUp(KeyEventArgs e)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;if (isNull)&lt;br /&gt;{&lt;br /&gt;Value = DateTime.Today;&lt;br /&gt;SetToDateTimeValue();&lt;br /&gt;}&lt;br /&gt;if (!isNull &amp;&amp;amp; e.KeyCode == Keys.Delete)&lt;br /&gt;{&lt;br /&gt;this.Value = null;&lt;br /&gt;OnValueChanged(EventArgs.Empty);&lt;br /&gt;}&lt;br /&gt;base.OnKeyUp(e);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-117032710533978220?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/117032710533978220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=117032710533978220&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/117032710533978220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/117032710533978220'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2007/02/yet-another-nullable-datetimepicker.html' title='Yet another Nullable DateTimePicker'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-117032654483585078</id><published>2007-02-01T02:10:00.000-08:00</published><updated>2007-02-01T02:42:24.886-08:00</updated><title type='text'>Reflection on Generic Lists for getting the item type</title><content type='html'>I needed to find out what kind of Generic list, I had created. But I did'nt find a reflection property to get the type.&lt;br /&gt;The type name of the generic list is [Namespace]  '1 [[   [Item Type your looking for ']]&lt;br /&gt;e.g.&lt;br /&gt;List&lt;string&gt; list = new list();&lt;br /&gt;Type listType = list.GetType();&lt;br /&gt;string listFullTypeName = listType.FullName;&lt;br /&gt;int idxStart = listFullTypeName.IndexOf("'1[[")+4;&lt;br /&gt;int idxEnd =listFullTypeName.IndexOf("]]");&lt;br /&gt;string itemTypeName = listFullTypeName.Substring(idxStart,idxEnd-idxStart);&lt;br /&gt;&lt;br /&gt;To get the real item type, I have to get the type from the itemTypeName string&lt;br /&gt;&lt;br /&gt;Type type = Type.GetType(itemTypeName);&lt;br /&gt;&lt;br /&gt;That's all&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-117032654483585078?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/117032654483585078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=117032654483585078&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/117032654483585078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/117032654483585078'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2007/02/reflection-on-generic-lists-for.html' title='Reflection on Generic Lists for getting the item type'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-116852251634051919</id><published>2007-01-10T23:18:00.000-08:00</published><updated>2007-01-13T05:05:36.136-08:00</updated><title type='text'>Create a Custom configuration section in the App.Config with C#</title><content type='html'>&lt;b&gt;Introduction&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;A custom section in the application configuration is defined as a Configuration Section. Derive a new class from the Configuration Section class and add some properties to it. The class should also be marked as serializable. The properties read and write string values from and to the application configuration file. For other value-types, cast the properties to the right type. Add for each property a Configuration Attribute or Element. The Configuration property will default thread the property as an attribute in the CacheConfigurationSection.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[Serializable]&lt;br /&gt;public class CacheConfigurationSection : ConfigurationSection&lt;br /&gt;&lt;br /&gt;[ConfigurationProperty("CacheExpirationTimeout", DefaultValue =&lt;br /&gt;"01:00:00",&lt;br /&gt;IsRequired = true)]&lt;br /&gt;public String CacheExpirationTimeout&lt;br /&gt;{&lt;br /&gt;get&lt;br /&gt;{ return (String)this["CacheExpirationTimeout"]; }&lt;br /&gt;set&lt;br /&gt;{ this["CacheExpirationTimeout"] = value; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[ConfigurationProperty("Enabled", DefaultValue =&lt;br /&gt;"true",&lt;br /&gt;IsRequired = true)]&lt;br /&gt;public bool Enabled&lt;br /&gt;{&lt;br /&gt;get&lt;br /&gt;{ return Convert.ToBoolean(this["Enabled"]); }&lt;br /&gt;set&lt;br /&gt;{ this["Enabled"] = value; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Validation attributes&lt;/b&gt;&lt;br /&gt;Because all values are of a given string type, additional validation have to b e made. Some attributes can be added to the properties to restrict the configuration values.&lt;br /&gt;&lt;br /&gt;Checking a string&lt;br /&gt;[StringValidator(InvalidCharacters = " ~!@#$%^&amp;*()[]{}/;'\"\\", MinLength = 1, MaxLength = 60)]&lt;br /&gt;&lt;br /&gt;Checking a long&lt;br /&gt;[LongValidator(MinValue = 1, MaxValue = 1000000, ExcludeRange = false)]&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Configuration XMLElementS instead of attributres&lt;/b&gt;&lt;br /&gt;Properties can be persisted as element. The property must be derived class from the baseclass configuration Element.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public class MyChildConfigElement : ConfigurationElement&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The child property is defined as any other property&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[ConfigurationProperty("myChildSection")]&lt;br /&gt;public MyChildConfigElement MyChildSection&lt;br /&gt;{&lt;br /&gt;…&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Changes to the application config file&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In the Application Configuration the section has to be declared&lt;br /&gt;&lt;br /&gt;Also the data of the Custom Configuration should be added&lt;br /&gt;&lt;code&gt;&lt;br /&gt;configuration&gt;&lt;br /&gt;configSections&gt;&lt;br /&gt;section name="CacheConfigurationSection" type="Company.Framework.Data.DTO.CacheConfigurationSection, Company.Framework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=564525624cd0845a" /&lt;br /&gt;/configSections&lt;br /&gt;&lt;br /&gt;CacheConfigurationSection DTOCacheFileName="ReferenceCache.xml" CacheExpirationTimeout="01:00:00" Enabled="true" /&lt;br /&gt;/configuration&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The publicKeyToken is the key that belongs to the strong name. If no strong name is used, the PublicKeyToken is null. With the Strong Name utilty the public key of the DLL can be retrieved. Usage: SN -T MyCustomSection.DLL.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Using the custom CacheConfigurationSection&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Get the section data with use of the Configuration Manager and cast the value to the Custom ConfigurationSection class.&lt;br /&gt;&lt;br /&gt;CacheConfigurationSection config =&lt;br /&gt;(CacheConfigurationSection) ConfigurationManager.GetSection("CacheConfigurationSection");&lt;br /&gt;&lt;br /&gt;//Now we can use it&lt;br /&gt;if (!config.Enabled)&lt;br /&gt;{&lt;br /&gt;return;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Source MSDN&lt;/b&gt;&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.configuration.configurationsection.aspx"&gt;Configuration Section&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/2tw134k3.aspx"&gt;Custom configuration Section&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-116852251634051919?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/116852251634051919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=116852251634051919&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116852251634051919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116852251634051919'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2007/01/create-custom-configuration-section-in.html' title='Create a Custom configuration section in the App.Config with C#'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-116731589932118521</id><published>2006-12-28T06:24:00.000-08:00</published><updated>2006-12-28T06:24:59.336-08:00</updated><title type='text'>CheckBoxCombo continued</title><content type='html'>The complete listening is here:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.ComponentModel;&lt;br /&gt;using System.Drawing;&lt;br /&gt;using System.Drawing.Design;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Windows.Forms;&lt;br /&gt;using System.Reflection;&lt;br /&gt;using System.Collections;&lt;br /&gt;namespace PlannerControl&lt;br /&gt;{&lt;br /&gt;    public class CheckBoxCombo : CustomComboBox &lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Occurs if the list changed&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        private ListChangedEventHandler listChangedHandler;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Occurs if the position changed&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        private EventHandler positionChangedHandler;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Occurs if the data source changes&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public EventHandler DataSourceChanged;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Occurs if the value member changes&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public EventHandler DisplayMemberChanged;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        private string displayMember;&lt;br /&gt;        private PropertyInfo propInfoItemDisplayMember;&lt;br /&gt;        private Dictionary&lt;int,object&gt; objectCollection;&lt;br /&gt;&lt;br /&gt;        private CheckedListBox checkedListBox;&lt;br /&gt;        &lt;br /&gt;        private object dataSource;&lt;br /&gt;        private string itemsDisplayMember;&lt;br /&gt;        private ControlPopup popup;&lt;br /&gt;        private PropertyInfo propInfoItemsDisplayMember;&lt;br /&gt;        private int listWidth;&lt;br /&gt;        private string allText="ALL";&lt;br /&gt;        private string checkAllText="Check All";&lt;br /&gt;        private string uncheckAllText="Uncheck All";&lt;br /&gt;        private bool autoContextMenu;&lt;br /&gt;        private CurrencyManager dataManager;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Get Checked Items&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;returns&gt;&lt;/returns&gt;&lt;br /&gt;        [Browsable(false) ]&lt;br /&gt;        public IEnumerator CheckedItemsEnumerator&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return checkedListBox.CheckedItems.GetEnumerator();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// True, if at least one item has been checked, otherwise returns false&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        [Browsable(false)]&lt;br /&gt;        public bool HasSelectedItems&lt;br /&gt;        {&lt;br /&gt;            get { return checkedListBox.CheckedItems.Count &gt; 0; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;br /&gt;&lt;br /&gt;        [Category("Appearance"),Description("Text for the default ContextMenu to check all items")]        &lt;br /&gt;        public string CheckAllText&lt;br /&gt;        {&lt;br /&gt;            get { return checkAllText; }&lt;br /&gt;            set { checkAllText = value; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        [Category("Appearance"), Description("Text for the default ContextMenu to uncheck all items")]        &lt;br /&gt;        public string UncheckAllText&lt;br /&gt;        {&lt;br /&gt;            get { return uncheckAllText; }&lt;br /&gt;            set { uncheckAllText = value; }&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt;        [Category("Appearance"), Description("Text that is displayed, if all items are checked.")]&lt;br /&gt;        public string AllText &lt;br /&gt;        {&lt;br /&gt;            get { return allText; }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                allText = value;&lt;br /&gt;                Invalidate();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        [Category("Appearance"), Description("If true sets an default ContextMenu to check and uncheck all items.")]&lt;br /&gt;        public bool AutoContextMenu&lt;br /&gt;        {&lt;br /&gt;            get { return autoContextMenu; }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                autoContextMenu = value;&lt;br /&gt;                SetContextMenu(value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Gets or Sets the backcolor of the dropdown list (including the combobox)&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        [Category("Appearance"), Description("Gets or sets the backcolor of the dropdown list."), BrowsableAttribute(true)]&lt;br /&gt;        public Color ListBackColor&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return this.checkedListBox.BackColor;&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                this.checkedListBox.BackColor = value;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// List width&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        [Category("Appearance"),Description("Gets or sets the list with of the checkedlistbox")]&lt;br /&gt;        public int ListWidth&lt;br /&gt;        {&lt;br /&gt;            get { return listWidth; }&lt;br /&gt;            set { &lt;br /&gt;                    listWidth = value;&lt;br /&gt;&lt;br /&gt;                    if (popup!=null)&lt;br /&gt;                    {&lt;br /&gt;                        listWidth = value;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Sets or Gets the ContextMenu of the CheckedListBox&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        [Category("Appearance"),Description("Gets or Sets the ContextMenu of the CheckedListBox")]&lt;br /&gt;        public ContextMenu ContextMenuListBox&lt;br /&gt;        {&lt;br /&gt;            get { return checkedListBox.ContextMenu  ; }&lt;br /&gt;            set {checkedListBox.ContextMenu = value; }&lt;br /&gt;        }&lt;br /&gt;                &lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Sets or Gets the ContextMenuStrip of the CheckedListBox&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        [Category("Appearance"), Description("Gets or sets the ContextMenuStrip of the CheckedListBox")]&lt;br /&gt;        public ContextMenuStrip ContextMenuStripListBox&lt;br /&gt;        {&lt;br /&gt;            get { return checkedListBox.ContextMenuStrip; }&lt;br /&gt;            set { checkedListBox.ContextMenuStrip = value; }&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// DataSource &lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        [Bindable(true)]&lt;br /&gt;        [TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design")]&lt;br /&gt;        [Category("Data")]&lt;br /&gt;        [DefaultValue(null)]&lt;br /&gt;        public object DataSource&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return dataSource;&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                dataSource = value;&lt;br /&gt;                DataBind();&lt;br /&gt;                OnDataSourceChanged(EventArgs.Empty);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// The record selected&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        [Browsable(false)]&lt;br /&gt;        protected CurrencyManager DataManager&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return this.dataManager;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Sets or Gets the DisplayMember of the DataSource&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        [Category("Data"),Description("Gets or sets the DisplayMember of the DataSource")]&lt;br /&gt;        [Editor("System.Windows.Forms.Design.DataMemberListEditor, System.Design",&lt;br /&gt;             "System.Drawing.Design.UITypeEditor, System.Drawing")]&lt;br /&gt;        [DefaultValue(null)]&lt;br /&gt;        public string DisplayMember&lt;br /&gt;        {&lt;br /&gt;            get { return displayMember; }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                displayMember = value;&lt;br /&gt;                OnDisplayMemberChanged(EventArgs.Empty);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Sets or Gets the ItemsDisplayMember&lt;br /&gt;        /// All Selected Items will be displayed with this item member in the TextBox Text&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        [Category("Data"),Description("Sets or gets the DisplayMember of the items in the ComboBox")]&lt;br /&gt;        public string ItemsDisplayMember&lt;br /&gt;        {&lt;br /&gt;            get { return itemsDisplayMember; }&lt;br /&gt;            set { itemsDisplayMember = value; propInfoItemsDisplayMember = null; }&lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;        /*&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Returns the checklistbox items&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        [Category("Data"), Description("Gets the CheckedListBox items")]&lt;br /&gt;        public CheckedListBox.ObjectCollection Items&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return checkedListBox.Items;  &lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        */&lt;br /&gt;        &lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Constructor&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public CheckBoxCombo()&lt;br /&gt;        {&lt;br /&gt;            InitializeComponent();&lt;br /&gt;            objectCollection = new Dictionary&lt;int,object&gt;(); &lt;br /&gt;            checkedListBox = new CheckedListBox();&lt;br /&gt;            listWidth = Width;&lt;br /&gt;            checkedListBox.CheckOnClick = true;&lt;br /&gt;            checkedListBox.Location = new Point(0, 0);&lt;br /&gt;            checkedListBox.ScrollAlwaysVisible = true;&lt;br /&gt;            listChangedHandler = new ListChangedEventHandler(dataManager_ListChanged);&lt;br /&gt;            positionChangedHandler = new EventHandler(dataManager_PositionChanged);&lt;br /&gt;            &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Returns true if a checked item is found&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;param name="item"&gt;&lt;/param&gt;&lt;br /&gt;        /// &lt;returns&gt;&lt;/returns&gt;&lt;br /&gt;        public bool ContainsCheckedItem(object item)&lt;br /&gt;        {&lt;br /&gt;            //Loop the collection of selected indices&lt;br /&gt;            for (int i = 0; i &lt; checkedListBox.SelectedIndices.Count; i++)&lt;br /&gt;            {&lt;br /&gt;                //Get the corresponding item&lt;br /&gt;                if (objectCollection[checkedListBox.SelectedIndices[i]]==item)&lt;br /&gt;                {&lt;br /&gt;                    return true;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return false;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Search the checked list for a given value&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;param name="property"&gt;&lt;/param&gt;&lt;br /&gt;        /// &lt;param name="value"&gt;&lt;/param&gt;&lt;br /&gt;        /// &lt;returns&gt;&lt;/returns&gt;&lt;br /&gt;        public bool ContainsCheckedValue(string property, object value)&lt;br /&gt;        {&lt;br /&gt;            ArrayList list = GetSelectedItems();&lt;br /&gt;            bool found = false;&lt;br /&gt;            if (list.Count &gt; 0)&lt;br /&gt;            {&lt;br /&gt;                PropertyInfo pi = list[0].GetType().GetProperty(property);&lt;br /&gt;                foreach (object item in list)&lt;br /&gt;                {&lt;br /&gt;                    if (pi.GetValue(item, null) == value)&lt;br /&gt;                    {&lt;br /&gt;                        found = true;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            return found;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        private void DataBind()&lt;br /&gt;        {&lt;br /&gt;            propInfoItemDisplayMember = null;&lt;br /&gt;            propInfoItemsDisplayMember = null;&lt;br /&gt;            &lt;br /&gt;            if (DataSource == null ||&lt;br /&gt;                base.BindingContext == null)&lt;br /&gt;                return;&lt;br /&gt;&lt;br /&gt;            CurrencyManager cm;&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                cm = base.BindingContext[this.DataSource] as CurrencyManager;&lt;br /&gt;            }&lt;br /&gt;            catch (ArgumentException)&lt;br /&gt;            {&lt;br /&gt;                // If no CurrencyManager was found&lt;br /&gt;                return;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            //Other currency manager&lt;br /&gt;            if (this.dataManager != cm)&lt;br /&gt;            {&lt;br /&gt;                // Unwire the old CurrencyManager&lt;br /&gt;                if (this.dataManager != null)&lt;br /&gt;                {&lt;br /&gt;                    this.dataManager.ListChanged -=&lt;br /&gt;                        listChangedHandler;&lt;br /&gt;                    this.dataManager.PositionChanged -=&lt;br /&gt;                        positionChangedHandler;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                checkedListBox.Items.Clear(); &lt;br /&gt;                this.dataManager = cm;&lt;br /&gt;                // Wire the new CurrencyManager&lt;br /&gt;                if (this.dataManager != null)&lt;br /&gt;                {&lt;br /&gt;                    this.dataManager.ListChanged +=&lt;br /&gt;                        listChangedHandler;&lt;br /&gt;                    this.dataManager.PositionChanged +=&lt;br /&gt;                        positionChangedHandler;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                // Update metadata and data&lt;br /&gt;                UpdateAllData();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void dataManager_PositionChanged(object sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            if (checkedListBox.Items.Count &gt; DataManager.Position)&lt;br /&gt;            {&lt;br /&gt;                checkedListBox.SelectedIndex =DataManager.Position;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        private void dataManager_ListChanged(object sender, ListChangedEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            if (e.ListChangedType == ListChangedType.Reset ||&lt;br /&gt;                e.ListChangedType == ListChangedType.ItemMoved)&lt;br /&gt;            {&lt;br /&gt;                // Update all data&lt;br /&gt;                UpdateAllData();&lt;br /&gt;            }&lt;br /&gt;            else if (e.ListChangedType == ListChangedType.ItemAdded)&lt;br /&gt;            {&lt;br /&gt;                // Add new Item&lt;br /&gt;                objectCollection.Add(e.NewIndex, dataManager.List[e.NewIndex]);&lt;br /&gt;                AddListItem(dataManager.List[e.NewIndex]);&lt;br /&gt;            }&lt;br /&gt;            else if (e.ListChangedType == ListChangedType.ItemChanged)&lt;br /&gt;            {&lt;br /&gt;                // Change Item&lt;br /&gt;                UpdateItem(e.NewIndex);&lt;br /&gt;            }&lt;br /&gt;            else if (e.ListChangedType == ListChangedType.ItemDeleted)&lt;br /&gt;            {&lt;br /&gt;                // Delete Item&lt;br /&gt;                DeleteItem(e.NewIndex);&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                // Update metadata and all data&lt;br /&gt;                &lt;br /&gt;                UpdateAllData();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Removes an item&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;param name="i"&gt;&lt;/param&gt;&lt;br /&gt;        private void DeleteItem(int i)&lt;br /&gt;        {&lt;br /&gt;            checkedListBox.Items.RemoveAt(i);&lt;br /&gt;            if (objectCollection.ContainsKey(i))&lt;br /&gt;            {&lt;br /&gt;                objectCollection.Remove(i);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void UpdateAllData()&lt;br /&gt;        {&lt;br /&gt;            checkedListBox.Items.Clear();&lt;br /&gt;            objectCollection.Clear();&lt;br /&gt;            for (int i = 0; i &lt; DataManager.Count; i++)&lt;br /&gt;            {&lt;br /&gt;                objectCollection.Add(i, dataManager.List[i]);&lt;br /&gt;                AddListItem(dataManager.List[i]);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void UpdateItem(int i)&lt;br /&gt;        {&lt;br /&gt;            object item = objectCollection[i];&lt;br /&gt;            checkedListBox.Items[i] = GetItemDisplayText(item);&lt;br /&gt;            &lt;br /&gt;            &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void AddListItem(object o)&lt;br /&gt;        {&lt;br /&gt;            string displayText = GetItemDisplayText(o);&lt;br /&gt;            checkedListBox.Items.Add(displayText); &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private string GetItemDisplayText(object o)&lt;br /&gt;        {&lt;br /&gt;            string displayText = String.Empty;&lt;br /&gt;            &lt;br /&gt;            if (!String.IsNullOrEmpty(this.displayMember))&lt;br /&gt;            {&lt;br /&gt;                if (propInfoItemDisplayMember == null)&lt;br /&gt;                {&lt;br /&gt;                    propInfoItemDisplayMember = o.GetType().GetProperty(this.displayMember);&lt;br /&gt;                }&lt;br /&gt;                object value = propInfoItemDisplayMember.GetValue(o,null);&lt;br /&gt;                if (value != null)&lt;br /&gt;                {&lt;br /&gt;                    displayText = value.ToString();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            else if (o != null)&lt;br /&gt;            {&lt;br /&gt;                displayText = o.ToString();&lt;br /&gt;            }&lt;br /&gt;            return displayText;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Retrieves the selected items from the list.&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;returns&gt;&lt;br /&gt;        /// The return value is an ArrayList&lt;br /&gt;        /// &lt;/returns&gt;&lt;br /&gt;        public ArrayList GetSelectedItems()&lt;br /&gt;        {&lt;br /&gt;            ArrayList listToReturn = new ArrayList();&lt;br /&gt;            if (checkedListBox.CheckedItems.Count &gt; 0)&lt;br /&gt;            {&lt;br /&gt;                foreach (int index in checkedListBox.CheckedIndices)&lt;br /&gt;                {&lt;br /&gt;                    listToReturn.Add(objectCollection[checkedListBox.CheckedIndices[index]]);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return listToReturn;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Return a list of values of the selected items&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;param name="valueMember"&gt;Value member of an list object&lt;/param&gt;&lt;br /&gt;        /// &lt;returns&gt;ArrayList&lt;/returns&gt;&lt;br /&gt;        public ArrayList GetSelectedItems(string valueMember)&lt;br /&gt;        {&lt;br /&gt;            ArrayList listToReturn = new ArrayList();&lt;br /&gt;            if (checkedListBox.CheckedItems.Count &gt; 0)&lt;br /&gt;            {&lt;br /&gt;                PropertyInfo pi = objectCollection[0].GetType().GetProperty(valueMember);&lt;br /&gt;                foreach (int index in checkedListBox.CheckedIndices)&lt;br /&gt;                {&lt;br /&gt;                    object value = pi.GetValue(objectCollection[checkedListBox.CheckedIndices[index]], null);&lt;br /&gt;                    listToReturn.Add(value);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return listToReturn;&lt;br /&gt;        }&lt;br /&gt;      &lt;br /&gt;    &lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Checks all items&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public void CheckAll()&lt;br /&gt;        {&lt;br /&gt;           for(int i=0;i&lt;checkedListBox.Items.Count;i++)&lt;br /&gt;           {&lt;br /&gt;               checkedListBox.SetItemChecked(i, true);  &lt;br /&gt;           }&lt;br /&gt;            &lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Returns the text for the ComboBox&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;returns&gt;&lt;/returns&gt;&lt;br /&gt;        private string GetComboBoxText()&lt;br /&gt;        {&lt;br /&gt;            //No items (checked)&lt;br /&gt;            if (checkedListBox.Items == null || checkedListBox.Items.Count == 0 || checkedListBox.CheckedIndices.Count == 0)&lt;br /&gt;            {&lt;br /&gt;                return "[]";&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            if (checkedListBox.CheckedIndices.Count==checkedListBox.Items.Count)&lt;br /&gt;            {&lt;br /&gt;                return String.Format("[{0}]", allText);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            //Get the member to be displayed&lt;br /&gt;            if (!String.IsNullOrEmpty(itemsDisplayMember) &amp;&amp; propInfoItemsDisplayMember == null)&lt;br /&gt;            {&lt;br /&gt;                propInfoItemsDisplayMember = objectCollection[0].GetType().GetProperty(itemsDisplayMember);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            StringBuilder displayText = new StringBuilder("[");&lt;br /&gt;            if (propInfoItemsDisplayMember ==null)&lt;br /&gt;            {&lt;br /&gt;                for(int itemIndex =0;itemIndex&lt;checkedListBox.CheckedIndices.Count;itemIndex++)&lt;br /&gt;                {&lt;br /&gt;                    object item = objectCollection[checkedListBox.CheckedIndices[itemIndex]]; &lt;br /&gt;                    displayText.Append(item.ToString());&lt;br /&gt;                    displayText.Append(", "); &lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                for(int itemIndex =0;itemIndex&lt;checkedListBox.CheckedIndices.Count;itemIndex++)&lt;br /&gt;                {&lt;br /&gt;                    object value = propInfoItemsDisplayMember.GetValue(objectCollection[checkedListBox.CheckedIndices[itemIndex]] , null);&lt;br /&gt;                    if (value==null)&lt;br /&gt;                    {&lt;br /&gt;                        value = String.Empty;&lt;br /&gt;                    }&lt;br /&gt;                    displayText.Append(value.ToString());&lt;br /&gt;                    displayText.Append(", ");&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            displayText.Remove(displayText.Length-2, 2); &lt;br /&gt;            displayText.AppendLine("]"); &lt;br /&gt;            return displayText.ToString();&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Sets a specific item checked&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;param name="index"&gt;&lt;/param&gt;&lt;br /&gt;        /// &lt;param name="value"&gt;&lt;/param&gt;&lt;br /&gt;        public void SetItemChecked(int index, bool value)&lt;br /&gt;        {&lt;br /&gt;             checkedListBox.SetItemChecked(index, value);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Unchecks all items&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public void UnCheckAll()&lt;br /&gt;        {&lt;br /&gt;            for (int i = 0; i &lt; checkedListBox.Items.Count; i++)&lt;br /&gt;            {&lt;br /&gt;                checkedListBox.SetItemChecked(i, false);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Occurs if datasource is changed&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public void OnDataSourceChanged(EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            &lt;br /&gt;            &lt;br /&gt;            if (DataSourceChanged != null)&lt;br /&gt;            {&lt;br /&gt;                DataSourceChanged(this, e);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// If the Default context menu is set to true, sets the context menu, else remove&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;param name="enable"&gt;&lt;/param&gt;&lt;br /&gt;        private void SetContextMenu(bool enable)&lt;br /&gt;        {&lt;br /&gt;            if (checkedListBox.ContextMenu == null &amp;&amp; enable)&lt;br /&gt;            {&lt;br /&gt;                ContextMenu contextMenu = new ContextMenu();&lt;br /&gt;                contextMenu.MenuItems.Add(checkAllText , delegate(object sender, EventArgs e) { CheckAll(); });&lt;br /&gt;                contextMenu.MenuItems.Add(uncheckAllText, delegate(object sender, EventArgs e) { UnCheckAll(); });&lt;br /&gt;                checkedListBox.ContextMenu = contextMenu;&lt;br /&gt;            }&lt;br /&gt;            if (!enable)&lt;br /&gt;            {&lt;br /&gt;                checkedListBox.ContextMenu = null;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;br /&gt;&lt;br /&gt;        &lt;br /&gt;        protected override void OnDropDownOpening()&lt;br /&gt;        {&lt;br /&gt;            base.OnDropDownOpening();&lt;br /&gt;            if (popup == null)&lt;br /&gt;            {&lt;br /&gt;                popup = new ControlPopup(this, checkedListBox);&lt;br /&gt;                popup.PopupClosed += new EventHandler&lt;EventArgs&gt;(PopupClosed);&lt;br /&gt;                popup.AddCloseKey(true, false, false, Keys.Up);&lt;br /&gt;                 &lt;br /&gt;            }&lt;br /&gt;            popup.Width = listWidth;&lt;br /&gt;            popup.Show();&lt;br /&gt;            &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;br /&gt;        private void PopupClosed(object sender,EventArgs empty)&lt;br /&gt;        {&lt;br /&gt;            Text = GetComboBoxText();&lt;br /&gt;            Invalidate(); &lt;br /&gt;        }&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;#if DEBUG&lt;br /&gt;&lt;br /&gt;        public CheckedListBox Box&lt;br /&gt;        {&lt;br /&gt;            get { return checkedListBox; }&lt;br /&gt;        }&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;        protected void OnDisplayMemberChanged(EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            &lt;br /&gt;            if (DisplayMemberChanged != null)&lt;br /&gt;            {&lt;br /&gt;                DisplayMemberChanged(this, e);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void InitializeComponent()&lt;br /&gt;        {&lt;br /&gt;            this.SuspendLayout();&lt;br /&gt;            // &lt;br /&gt;            // CheckBoxCombo&lt;br /&gt;            // &lt;br /&gt;            this.AutoSize = true;&lt;br /&gt;            this.Name = "CheckBoxCombo";&lt;br /&gt;            this.Size = new System.Drawing.Size(305, 20);&lt;br /&gt;            &lt;br /&gt;            this.ResumeLayout(false);&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;       &lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-116731589932118521?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/116731589932118521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=116731589932118521&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116731589932118521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116731589932118521'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/12/checkboxcombo-continued.html' title='CheckBoxCombo continued'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-116731567128012544</id><published>2006-12-28T06:00:00.000-08:00</published><updated>2006-12-28T06:23:58.830-08:00</updated><title type='text'>CheckBoxCombo</title><content type='html'>If you read my previous posts, you noticed the PopupControl and the Custom Combobox.&lt;br /&gt;Now, it's time to fit it together in a CheckedListBox.&lt;br /&gt;&lt;br /&gt;I start with deriving a class from CustomComboBox&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public class CheckBoxCombo : CustomComboBox&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The popup control will be shown if the dropdown action is triggered.&lt;br /&gt;Override the OnDropDownOpening and add the popup and shows it. I also add a close key to close the popup with keyboard key ALT-UP. If, the popup is closed then, I will reset the ComboBox text with the selected items.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;protected override void OnDropDownOpening()&lt;br /&gt;{&lt;br /&gt;base.OnDropDownOpening();&lt;br /&gt;if (popup == null)&lt;br /&gt;{&lt;br /&gt;popup = new ControlPopup(this, checkedListBox);&lt;br /&gt;popup.PopupClosed += new EventHandler&lt;eventargs&gt;(PopupClosed);&lt;br /&gt;popup.AddCloseKey(true, false, false, Keys.Up);&lt;br /&gt;}&lt;br /&gt;popup.Width = listWidth;&lt;br /&gt;popup.Show();&lt;br /&gt;}&lt;br /&gt;private void PopupClosed(object sender,EventArgs empty)&lt;br /&gt;{&lt;br /&gt;Text = GetComboBoxText();&lt;br /&gt;Invalidate();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I add the CheckListBox control to the popup form. Because, I don't like doubleclicks, I set the CheckOnClick true;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;checkedListBox.CheckOnClick = true;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The CheckedListBox does not contain DataSource capabilities. I have to implement it myself. The display text attribute is an attribute of an item object. This display text will be added to the CheckedListBox. I store the actual values in a Dictionary Object. With the CheckedIndices property of the CheckedListBox, I can resolve the value(s) of the selected item(s).&lt;br /&gt;I also add a currency manager, to bind the control to a datasource. The datasource is an object, but with the right typeconverter it is more convenient to set it at design time. Notice, that I don't have a value member. This represents the item object itself.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private Dictionary&lt;int,object&gt; objectCollection;&lt;br /&gt;private CurrencyManager dataManager;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// DataSource &lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        [Bindable(true)]&lt;br /&gt;        [TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design")]&lt;br /&gt;        [Category("Data")]&lt;br /&gt;        [DefaultValue(null)]&lt;br /&gt;        public object DataSource&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return dataSource;&lt;br /&gt;            }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                dataSource = value;&lt;br /&gt;                DataBind();&lt;br /&gt;                OnDataSourceChanged(EventArgs.Empty);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt; private void DataBind()&lt;br /&gt;        {&lt;br /&gt;            propInfoItemDisplayMember = null;&lt;br /&gt;            propInfoItemsDisplayMember = null;&lt;br /&gt;            &lt;br /&gt;            if (DataSource == null ||&lt;br /&gt;                base.BindingContext == null)&lt;br /&gt;                return;&lt;br /&gt;&lt;br /&gt;            CurrencyManager cm;&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                cm = base.BindingContext[this.DataSource] as CurrencyManager;&lt;br /&gt;            }&lt;br /&gt;            catch (ArgumentException)&lt;br /&gt;            {&lt;br /&gt;                // If no CurrencyManager was found&lt;br /&gt;                return;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            //Other currency manager&lt;br /&gt;            if (this.dataManager != cm)&lt;br /&gt;            {&lt;br /&gt;                // Unwire the old CurrencyManager&lt;br /&gt;                if (this.dataManager != null)&lt;br /&gt;                {&lt;br /&gt;                    this.dataManager.ListChanged -=&lt;br /&gt;                        listChangedHandler;&lt;br /&gt;                    this.dataManager.PositionChanged -=&lt;br /&gt;                        positionChangedHandler;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                checkedListBox.Items.Clear(); &lt;br /&gt;                this.dataManager = cm;&lt;br /&gt;                // Wire the new CurrencyManager&lt;br /&gt;                if (this.dataManager != null)&lt;br /&gt;                {&lt;br /&gt;                    this.dataManager.ListChanged +=&lt;br /&gt;                        listChangedHandler;&lt;br /&gt;                    this.dataManager.PositionChanged +=&lt;br /&gt;                        positionChangedHandler;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                // Update metadata and data&lt;br /&gt;                UpdateAllData();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The items in the CheckListBox, need to have the same index as the items in my private variable objectCollection. The DataBind() method fills the CheckedListBox items and the real object collection.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt; private void UpdateAllData()&lt;br /&gt;        {&lt;br /&gt;            checkedListBox.Items.Clear();&lt;br /&gt;            objectCollection.Clear();&lt;br /&gt;            for (int i = 0; i &lt; DataManager.Count; i++)&lt;br /&gt;            {&lt;br /&gt;                objectCollection.Add(i, dataManager.List[i]);&lt;br /&gt;                AddListItem(dataManager.List[i]);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-116731567128012544?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/116731567128012544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=116731567128012544&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116731567128012544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116731567128012544'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/12/checkboxcombo.html' title='CheckBoxCombo'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-116720976280348601</id><published>2006-12-27T00:42:00.000-08:00</published><updated>2006-12-28T05:59:53.963-08:00</updated><title type='text'>Custom ComboBox</title><content type='html'>Microsoft introduces more and more themesupport for (custom) controls. In Windows 2000, I used ControlPaint to draw my controls. In Windows XP, each control has got its own renderer. This renderer knows how to draw an control according any choosen XP theme. I create a custom ComboBox and found a good example at &lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.comboboxrenderer.aspx"&gt;MSDN&lt;/a&gt;. I customized it and extended it to have better focus support . I have enter ALT-DOWN twice to get the drop list down. I added a focus rectangle and some focus support.&lt;br /&gt;&lt;br /&gt;Here is my code&lt;br /&gt;&lt;code&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Drawing;&lt;br /&gt;using System.Drawing.Drawing2D;&lt;br /&gt;using System.Drawing.Text;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Windows.Forms;&lt;br /&gt;using System.Windows.Forms.VisualStyles;&lt;br /&gt;&lt;br /&gt;namespace MsDotnet.Windows.Forms&lt;br /&gt;{&lt;br /&gt;public class CustomComboBox : Control&lt;br /&gt;{&lt;br /&gt;// ContainsFocus --&gt; ShowFocusCues&lt;br /&gt;// ChangeUICues --&gt; This is the event that is raised if Windows detects that some aspect of the focus or the focus cues may have changed&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Occurs if the drop down is being opened&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;public EventHandler DropDownOpening;&lt;br /&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Occurs if the drop down is being closed&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;public EventHandler DropDownClosing;&lt;br /&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Paints the drop down control&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;public EventHandler&lt;painteventargs&gt; PaintDropDownControl;&lt;br /&gt;&lt;br /&gt;private Size arrowSize;&lt;br /&gt;private Rectangle arrowRectangle;&lt;br /&gt;private Rectangle topTextBoxRectangle;&lt;br /&gt;&lt;br /&gt;private ComboBoxState textBoxState = ComboBoxState.Normal;&lt;br /&gt;private ComboBoxState arrowState = ComboBoxState.Normal;&lt;br /&gt;private bool isActivated = false;&lt;br /&gt;&lt;br /&gt;public CustomComboBox()&lt;br /&gt;: base()&lt;br /&gt;{&lt;br /&gt;this.Location = new Point(10, 10);&lt;br /&gt;this.Size = new Size(140, 38);&lt;br /&gt;this.Font = SystemFonts.IconTitleFont;&lt;br /&gt;this.Text = String.Empty;&lt;br /&gt;&lt;br /&gt;// Initialize the rectangles to look like the standard combo&lt;br /&gt;// box control.&lt;br /&gt;arrowSize = new Size(18, 20);&lt;br /&gt;arrowRectangle = new Rectangle(ClientRectangle.X +&lt;br /&gt;ClientRectangle.Width - arrowSize.Width - 1,&lt;br /&gt;ClientRectangle.Y + 1,&lt;br /&gt;arrowSize.Width,&lt;br /&gt;arrowSize.Height);&lt;br /&gt;topTextBoxRectangle = new Rectangle(ClientRectangle.X,&lt;br /&gt;ClientRectangle.Y,&lt;br /&gt;ClientRectangle.Width,&lt;br /&gt;arrowSize.Height + 2);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected override void OnChangeUICues(UICuesEventArgs e)&lt;br /&gt;{&lt;br /&gt;Invalidate();&lt;br /&gt;base.OnChangeUICues(e);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected override bool ProcessMnemonic(char charCode)&lt;br /&gt;{&lt;br /&gt;if (Enabled &amp;&amp;amp; Visible&lt;br /&gt;&amp;&amp;amp; IsMnemonic(charCode, this.Text))&lt;br /&gt;{&lt;br /&gt;// Perform action associated with mnemonic&lt;br /&gt;// Moves focus to our control&lt;br /&gt;Focus();&lt;br /&gt;Invalidate();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;return true;&lt;br /&gt;}&lt;br /&gt;return false;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Draw the combobox in the current state&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;/// &lt;param name="e"&gt;&lt;/param&gt;&lt;br /&gt;protected override void OnPaint(PaintEventArgs e)&lt;br /&gt;{&lt;br /&gt;//base.OnPaint(e);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if (!ComboBoxRenderer.IsSupported)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;return;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Always draw the main text box and drop down arrow in their&lt;br /&gt;// current states&lt;br /&gt;ComboBoxRenderer.DrawTextBox(e.Graphics, topTextBoxRectangle,&lt;br /&gt;Text, this.Font, textBoxState);&lt;br /&gt;ComboBoxRenderer.DrawDropDownButton(e.Graphics, arrowRectangle,&lt;br /&gt;arrowState);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if (ContainsFocus)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;Rectangle focRect = topTextBoxRectangle;&lt;br /&gt;focRect.Inflate(-2, -2);&lt;br /&gt;ControlPaint.DrawFocusRectangle(e.Graphics, focRect);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// Only draw the bottom text box if the arrow has been clicked&lt;br /&gt;if (isActivated)&lt;br /&gt;{&lt;br /&gt;OnPaintDropDownControl(e);&lt;br /&gt;/*ComboBoxRenderer.DrawTextBox(e.Graphics,&lt;br /&gt;bottomTextBoxRectangle, bottomText, this.Font,&lt;br /&gt;textBoxState);*/&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Occurs if the down arrow was pressed&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;/// &lt;param name="e"&gt;&lt;/param&gt;&lt;br /&gt;protected virtual void OnPaintDropDownControl(PaintEventArgs e)&lt;br /&gt;{&lt;br /&gt;if (PaintDropDownControl != null)&lt;br /&gt;{&lt;br /&gt;PaintDropDownControl(this, e);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected override void OnResize(EventArgs e)&lt;br /&gt;{&lt;br /&gt;topTextBoxRectangle.Width = ClientRectangle.Width;&lt;br /&gt;arrowRectangle.X = ClientRectangle.X + ClientRectangle.Width - arrowRectangle.Width-1;&lt;br /&gt;if (Height!=topTextBoxRectangle.Height)&lt;br /&gt;{&lt;br /&gt;Height = topTextBoxRectangle.Height;&lt;br /&gt;}&lt;br /&gt;base.OnResize(e);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected override void OnMouseDown(MouseEventArgs e)&lt;br /&gt;{&lt;br /&gt;base.OnMouseDown(e);&lt;br /&gt;&lt;br /&gt;// Check whether the user clicked the arrow.&lt;br /&gt;if (arrowRectangle.Contains(e.Location) &amp;&amp;amp;&lt;br /&gt;ComboBoxRenderer.IsSupported)&lt;br /&gt;{&lt;br /&gt;TriggerDropDown();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;protected override void OnKeyDown(KeyEventArgs e)&lt;br /&gt;{&lt;br /&gt;if (e.KeyCode == Keys.Down &amp;&amp;amp; e.Alt)&lt;br /&gt;{ &lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;isActivated = false;&lt;br /&gt;TriggerDropDown();&lt;br /&gt;arrowState = ComboBoxState.Normal;&lt;br /&gt;Invalidate();&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;base.OnKeyDown(e);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;private void TriggerDropDown()&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;//Set the focus&lt;br /&gt;if (!ContainsFocus)&lt;br /&gt;{&lt;br /&gt;Focus();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt;// Draw the arrow in the pressed state.&lt;br /&gt;arrowState = ComboBoxState.Pressed;&lt;br /&gt;&lt;br /&gt;// The user has activated the combo box.&lt;br /&gt;if (!isActivated)&lt;br /&gt;{&lt;br /&gt;OnDropDownOpening();&lt;br /&gt;textBoxState = ComboBoxState.Pressed;&lt;br /&gt;isActivated = true;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// The user has deactivated the combo box.&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;OnDropDownClosing();&lt;br /&gt;textBoxState = ComboBoxState.Normal;&lt;br /&gt;isActivated = false;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Redraw the control.&lt;br /&gt;Invalidate();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected virtual void OnDropDownClosing()&lt;br /&gt;{&lt;br /&gt;if (DropDownClosing != null)&lt;br /&gt;{&lt;br /&gt;DropDownClosing(this, EventArgs.Empty);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected virtual void OnDropDownOpening()&lt;br /&gt;{&lt;br /&gt;if (DropDownOpening != null)&lt;br /&gt;{&lt;br /&gt;DropDownOpening(this, EventArgs.Empty);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected override void OnGotFocus(EventArgs e)&lt;br /&gt;{&lt;br /&gt;Invalidate();&lt;br /&gt;base.OnGotFocus(e);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected override void OnLostFocus(EventArgs e)&lt;br /&gt;{&lt;br /&gt;Invalidate();&lt;br /&gt;base.OnLostFocus(e);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected override void OnMouseUp(MouseEventArgs e)&lt;br /&gt;{&lt;br /&gt;base.OnMouseUp(e);&lt;br /&gt;&lt;br /&gt;if (arrowRectangle.Contains(e.Location) &amp;&amp;amp;&lt;br /&gt;ComboBoxRenderer.IsSupported)&lt;br /&gt;{&lt;br /&gt;arrowState = ComboBoxState.Normal;&lt;br /&gt;Invalidate();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-116720976280348601?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/116720976280348601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=116720976280348601&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116720976280348601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116720976280348601'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/12/custom-combobox.html' title='Custom ComboBox'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-116720893150824398</id><published>2006-12-27T00:19:00.000-08:00</published><updated>2006-12-27T00:42:11.523-08:00</updated><title type='text'>Control propup</title><content type='html'>I was wondering how the combobox listbox shows up? &lt;br /&gt;This seems to be a form like control. I googled on the internet and found &lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.controls.primitives.popup.aspx"&gt; a new Windows form popup control&lt;/a&gt;. This is part of .NET Framework 3.0. Because, I still use 2.0, there is no alternative. I found a suggestion to use a Toolstrip control. This control is a context menu control, that is able to host any control. But, it behaves like a context menu and therefore does not suite my needs. I decided to write a popup form that can show the control and close. BTW: I definitely not use the Infragistics popupcontainer. It stays showed, if another application is activated. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is the result.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Drawing;&lt;br /&gt;using System.Windows.Forms;&lt;br /&gt;&lt;br /&gt;namespace MsDotNet.Windows.Forms;&lt;br /&gt;{&lt;br /&gt;    public class ControlPopup : Form&lt;br /&gt;    {&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Occurs if the form is closed&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public EventHandler&lt;EventArgs&gt; PopupClosed;&lt;br /&gt;&lt;br /&gt;        #region member variables&lt;br /&gt;        public struct CloseKey&lt;br /&gt;        {&lt;br /&gt;            public bool Alt;&lt;br /&gt;            public bool Control;&lt;br /&gt;            public bool Shift;&lt;br /&gt;            public Keys KeyCode;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;br /&gt;        private Control control;&lt;br /&gt;        private List&lt;CloseKey&gt; closeKeys=new List&lt;CloseKey&gt;();&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region properties&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        public List&lt;CloseKey&gt; CloseKeys&lt;br /&gt;        {&lt;br /&gt;            get { return closeKeys; }&lt;br /&gt;            &lt;br /&gt;        }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Popup control&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public Control Control&lt;br /&gt;        {&lt;br /&gt;            get { return control; }&lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                Controls.Clear();&lt;br /&gt;                control = value;&lt;br /&gt;                if (control != null)&lt;br /&gt;                {&lt;br /&gt;                    Height = control.Height;&lt;br /&gt;                    control.Leave += new EventHandler(PopForm_Leave);&lt;br /&gt;                    control.KeyDown += new KeyEventHandler(OnControlKeyDown);&lt;br /&gt;                    control.LostFocus += new EventHandler(control_LostFocus);&lt;br /&gt;                    Controls.Add(control);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region ctor&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Default constructor&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public ControlPopup()&lt;br /&gt;        {&lt;br /&gt;            TopMost = true;&lt;br /&gt;            FormBorderStyle = FormBorderStyle.None;&lt;br /&gt;            ShowInTaskbar = false;&lt;br /&gt;            StartPosition = FormStartPosition.Manual;&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Consturctor that adds the control and set the dockstyle of the control to Fill&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;param name="owner"&gt;&lt;/param&gt;&lt;br /&gt;        /// &lt;param name="control"&gt;&lt;/param&gt;&lt;br /&gt;        public ControlPopup(Control owner, Control control)&lt;br /&gt;            : this()&lt;br /&gt;        {&lt;br /&gt;            Location = owner.PointToScreen(new Point(0, owner.Height));&lt;br /&gt;            Control = control;&lt;br /&gt;            control.Dock = DockStyle.Fill;&lt;br /&gt;        }&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Adds a popup close key&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;param name="alt"&gt;&lt;/param&gt;&lt;br /&gt;        /// &lt;param name="shift"&gt;&lt;/param&gt;&lt;br /&gt;        /// &lt;param name="control"&gt;&lt;/param&gt;&lt;br /&gt;        /// &lt;param name="key"&gt;&lt;/param&gt;&lt;br /&gt;        public void AddCloseKey(bool alt, bool shift, bool control, Keys key)&lt;br /&gt;        {&lt;br /&gt;            CloseKey closeKey = new CloseKey();&lt;br /&gt;            closeKey.Alt = alt;&lt;br /&gt;            closeKey.Shift = shift;&lt;br /&gt;            closeKey.Control = control;&lt;br /&gt;            closeKey.KeyCode = key;&lt;br /&gt;            closeKeys.Add(closeKey); &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// hides the popup form, does not close it.&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        private void OnHide()&lt;br /&gt;        {&lt;br /&gt;            if (this.Visible)&lt;br /&gt;            {&lt;br /&gt;                Hide();&lt;br /&gt;            }&lt;br /&gt;            if (PopupClosed != null)&lt;br /&gt;            {&lt;br /&gt;                PopupClosed(this, EventArgs.Empty);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        protected override void OnLostFocus(EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            if (!Control.Focused)&lt;br /&gt;            {&lt;br /&gt;                OnHide();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        void control_LostFocus(object sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            OnHide();&lt;br /&gt;        }&lt;br /&gt;            &lt;br /&gt;&lt;br /&gt;        void PopForm_Leave(object sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            OnHide();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        protected void OnControlKeyDown(object sender,KeyEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            foreach (CloseKey closeKey in closeKeys)&lt;br /&gt;            {&lt;br /&gt;                if (e.Alt == closeKey.Alt &amp;&amp;&lt;br /&gt;                    e.Control == closeKey.Control &amp;&amp;&lt;br /&gt;                    e.Shift == closeKey.Shift &amp;&amp;&lt;br /&gt;                    e.KeyCode == closeKey.KeyCode)&lt;br /&gt;                {&lt;br /&gt;                    OnHide();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;br /&gt;&lt;br /&gt;        private void InitializeComponent()&lt;br /&gt;        {&lt;br /&gt;            this.SuspendLayout();&lt;br /&gt;            // &lt;br /&gt;            // ControlPopup&lt;br /&gt;            // &lt;br /&gt;            this.ClientSize = new System.Drawing.Size(292, 262);&lt;br /&gt;            this.Name = "ControlPopup";&lt;br /&gt;            this.ResumeLayout(false);&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I included a list of CloseKeys. I need my control to have keyboardsupport to close the popup. In my case. I needed ALT-UP to close the popup.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-116720893150824398?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/116720893150824398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=116720893150824398&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116720893150824398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116720893150824398'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/12/control-propup.html' title='Control propup'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-116604642986909370</id><published>2006-12-13T13:19:00.000-08:00</published><updated>2006-12-13T14:47:36.203-08:00</updated><title type='text'>Customizing the DataGridView</title><content type='html'>Most people looking for the subject ends with the ASP.NET version of the control. I am wondering how the DataGridView of a windows form can be extended?&lt;br /&gt;&lt;br /&gt;At MSDN an &lt;a href="http://msdn2.microsoft.com/en-us/library/7tas5c80.aspx"&gt;article was published&lt;/a&gt; how to host or create custom columns. Also changing the row appearance can be customized according to &lt;a href="http://msdn2.microsoft.com/en-us/library/85kxk29c.aspx"&gt;this article&lt;/a&gt;. At code project an article is published how to print content of the &lt;a href="http://www.codeproject.com/csharp/PrintDataGridView.asp"&gt;DataGridView control&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-116604642986909370?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/116604642986909370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=116604642986909370&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116604642986909370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116604642986909370'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/12/customizing-datagridview.html' title='Customizing the DataGridView'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-116604347386894047</id><published>2006-12-13T12:36:00.000-08:00</published><updated>2006-12-13T13:18:30.223-08:00</updated><title type='text'>Multi column Combobox</title><content type='html'>Building your own ComboBox control is not as hard as it seems. There is already a ComboBox control available that can be fully customized. Add a class to your visual studio sulution and derive from the ComboBox class. You can make your own list of owner draw items. Set the DrawMode property to&lt;br /&gt;DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable or OwnerDrawFixed. If the DrawMode is variable each item in the list has it's own height or with. If the Drawmode is Fixed each item has the same size and depends on the ItemWidth or ItemHeight property of the ComboBox.&lt;br /&gt;&lt;br /&gt;With DrawMode is OwnerDrawVariable the OnMeasueItem has to be overriden to set the custom size of the item.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;protected override void OnMeasureItem(MeasureItemEventArgs e)&lt;br /&gt;{&lt;br /&gt; if (e.Index % 2 == 0)&lt;br /&gt; {&lt;br /&gt;   e.ItemHeight = 20;&lt;br /&gt; }&lt;br /&gt;else&lt;br /&gt; {&lt;br /&gt;  e.ItemHeight = 10;&lt;br /&gt; }&lt;br /&gt; e.ItemWidth = 50;&lt;br /&gt; base.OnMeasureItem(e);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Override the OnDrawItem(DrawItemEventArgs e) event to draw the custom items.&lt;br /&gt;To draw the custom list item the following help methods and properties are made available&lt;br /&gt;&lt;br /&gt;e.Index // List item index, value of -1 is the selected item&lt;br /&gt;e.DrawBackground() //Draws the background&lt;br /&gt;e.DrawFocusRectangle(); //Draws a focus rectangle&lt;br /&gt;e.Bounds; Canvas graphics size/Bounds&lt;br /&gt;e.Graphics //Canvas graphics to paint the item&lt;br /&gt;e.DrawItemState //State of the item: Checked, Focus, Selected,  Grayed, Inactive etc..&lt;br /&gt;&lt;br /&gt;If the item is a text item, use the DrawString to draw the text&lt;br /&gt;e.Graphics.DrawString(text , Font, new SolidBrush(e.ForeColor), e.Bounds);&lt;br /&gt;&lt;br /&gt;Use a string format to align the text drawn in the bounds.&lt;br /&gt;&lt;br /&gt;e.g.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;StringFormat format = new StringFormat();&lt;br /&gt;format.Alignment = StringAlignment.Center;  //Center text in the rectangle&lt;br /&gt;e.Graphics.DrawString(value, Font, new SolidBrush(ForeColor),e.Bounds,format);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Examples&lt;br /&gt;&lt;a href="http://www.devx.com/dotnet/Article/8014/0/page/3"&gt;Color ComboBox&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/cs/combobox/ImageCombo_NET.asp"&gt;Image ComboBox&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-116604347386894047?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/116604347386894047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=116604347386894047&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116604347386894047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116604347386894047'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/12/multi-column-combobox.html' title='Multi column Combobox'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-116522354610763415</id><published>2006-12-03T23:40:00.000-08:00</published><updated>2006-12-04T01:20:01.076-08:00</updated><title type='text'>How to convert a class to a DataTable object.</title><content type='html'>In Visual Studio 2005, there is support for objects. In Asp.net there is an object data source and in Windows forms there is a binding source. In most cases this binding support is sufficient, however sometimes a real DataTable object is needed. &lt;br /&gt;I notice more and more that Microsoft focuses more on Web application development then Windows application development. The Treeview control of the Winforms environment does not work with a handy XML DataSource for example. &lt;br /&gt;The question is what the best way to convert is. To main options can be chosen. The first way is to convert it to XML and load it in a DataSet. The second way is to use reflection and create a DataTable on the fly by using reflection. &lt;br /&gt;&lt;br /&gt;public static DataTable SerializeAs(List&lt;T&gt; items)&lt;br /&gt;{&lt;br /&gt;  MemoryStream stream = new MemoryStream();                               &lt;br /&gt;  XmlSerializer serializer = new XmlSerializer(typeof(List&lt;T&gt;));&lt;br /&gt;  serializer.Serialize(stream , items);&lt;br /&gt;  stream.Position = 0;&lt;br /&gt;  DataSet set = new DataSet();&lt;br /&gt;  set.ReadXml(stream);&lt;br /&gt;  DataTable test = set.Tables[0];&lt;br /&gt;  return test;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public static DataTable ToDataTable(List&lt;T&gt; items)&lt;br /&gt; {&lt;br /&gt;   DataTable dt = new DataTable();&lt;br /&gt;   Type tType = typeof(T);&lt;br /&gt;   PropertyInfo[] props = tType.GetProperties();&lt;br /&gt;   foreach (PropertyInfo prop in props)&lt;br /&gt;    {&lt;br /&gt;     DataColumn col = new DataColumn(prop.Name,prop.PropertyType);&lt;br /&gt;     dt.Columns.Add(col);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    foreach (T item in items) &lt;br /&gt;    {&lt;br /&gt;     DataRow dr = dt.NewRow();&lt;br /&gt;     foreach (PropertyInfo prop in props)&lt;br /&gt;     {&lt;br /&gt;       dr[prop.Name] = prop.GetValue(item, null);&lt;br /&gt;     }&lt;br /&gt;     dt.Rows.Add(dr);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; return dt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;The question is, which code fragment is better? It’s not easy to say. The XML serialization takes more time. I measured the elapsed time with the Stopwatch class (namespace System.Diagnostics). In the execution it was XML serialization  takes 330 ms against and serialization with reflection only takse 4 ms. &lt;br /&gt;XML serialization also creates more relevant metadata. This include(s): the reference table(s) also being converted to DataTable objects, an automatic incremented ID field, and some datatype settings. &lt;br /&gt;Serialization by reflection serializes reference tables with their original class types. Classes used as referenced fields should have a type converter to persist information in the correct format to the database. An correct ToString() override implementation could also sufficient. I can easily extend the serialization method to store more information in the DataTable object. Another charistics of this method is that the class does not need to be serializable.&lt;br /&gt;&lt;br /&gt;In most cases, the XML serialization is more safe. The DataSet object that is used for storage will be accessible as long the DataTable object which is part of the object refers to it. &lt;br /&gt;The serialization with reflection has more performance and will fit in lot of cases. The serilization method has less capabilities, but this method can also easily be extended to meet the needs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-116522354610763415?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/116522354610763415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=116522354610763415&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116522354610763415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116522354610763415'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/12/how-to-convert-class-to-datatable.html' title='How to convert a class to a DataTable object.'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-116489297169502458</id><published>2006-11-30T02:14:00.000-08:00</published><updated>2006-11-30T05:22:51.743-08:00</updated><title type='text'>Web Service Contract First</title><content type='html'>Adding and using a webservice in an application seems to be very simple. Just add a web reference to your project, enter the URI of the webservice and there you go. You can direct call web methods from your application. Web method parameters can be of a simple type like a string, but also of a complex type. The web reference has automatically created classes for these complex types.&lt;br /&gt;The complex types are Data Transfer Objects, but reside in the project which added the web reference. If you like to use the DTO's in another project of the solution, a second web reference is needed. It would be better, if the complex types of the Web service could be place in an own project.&lt;br /&gt;The tool Web Service Contract First from Thinktecture analyses the web service description language and generate classes for all web service method calls and complex types. These classes containing the complex types can be stored in a separate project to be used at DTO's. A web reference in this project is not needed anymore.&lt;br /&gt;&lt;br /&gt;The tool offers of course more then just this one option. It's possible to create a WSDL from an existing XSD. With the WSDL it is possible to generate server of client interface data code.&lt;br /&gt;&lt;br /&gt;Links&lt;br /&gt;&lt;a href="http://www.thinktecture.com/Resources/Software/WSContractFirst/default.html#Download"&gt;WSCF version 0.7&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-116489297169502458?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/116489297169502458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=116489297169502458&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116489297169502458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116489297169502458'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/11/web-service-contract-first.html' title='Web Service Contract First'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-116228530797097145</id><published>2006-10-31T00:39:00.000-08:00</published><updated>2006-11-13T02:06:02.610-08:00</updated><title type='text'>Installer class</title><content type='html'>If you install an application with an MSI installer, a setup project is needed.&lt;br /&gt;Sometimes it's handy to customize it. The interface is hard to change. You can add some default forms, set the captions, value source and default values. Of course it's possible to create your own forms in an installer class. The interaction between the installer and installer class is very thin. The values are passed as command line arguments to the installer class, which easily can lead to error's.&lt;br /&gt;&lt;br /&gt;I have created an installer class to make an application setting dynamical during installation. I added an installer project and overrided the method&lt;br /&gt;'override void Install(System.Collections.IDictionary stateSaver)'&lt;br /&gt;There are several installation stadia to do custom actions, but I'll have to do it during installation.&lt;br /&gt;&lt;br /&gt;Because the installer class, runs a seperate dll application it's hard to communicate with the installer. What would be the installation directory for example?&lt;br /&gt;The target path is the assembly path without the executable name.  This parameter is automatically added to the installer context. I just have to read it out in code.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;exeFilePath = Path.GetDirectoryName(Context.Parameters["assemblypath"]), [Target executable]).&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I added the installer application as primary output to the customer install action of the setup project and set the 'CustomDataAction' to '/WebserviceEndPoint=[WEBSERVICEURL]'&lt;br /&gt;The first value is the command line parametername and the second value is a value set by a default custom installation form (Textboxes (A).&lt;br /&gt;In my installer class the parameter is now made available in the context. I read the value in the install method&lt;br /&gt;&lt;br /&gt;&lt;code&gt;setting = Context.Parameters["WebserviceEndPoint"];&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In the interface editor, I added a 'TextBoxes (A) ' form and set the properties like this. Textboxes which you don't use, make them invisible.&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/7872/820/1600/setupinterface%20(Small).jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/7872/820/320/setupinterface%20%28Small%29.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next, I have to change the config file with the webservice endpoint value that was entered during installation. I added the following code to comply this.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Configuration config =&lt;br /&gt;ConfigurationManager.OpenExeConfiguration(exeFilePath);&lt;br /&gt;config.AppSettings.Settings["ServiceEndpointURL"].Value = setting;&lt;br /&gt;config.Save(ConfigurationSaveMode.Modified);&lt;br /&gt;base.Install(stateSaver);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If you wish to debug an installer class, put a messagebox in the top of code to debug. If the messagebox is triggered during the installation process, attach a remote debugger to it and choose break all or add a breakpoint on the next line of the messagebox code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-116228530797097145?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/116228530797097145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=116228530797097145&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116228530797097145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116228530797097145'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/10/installer-class.html' title='Installer class'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-116228394716292048</id><published>2006-10-31T00:08:00.000-08:00</published><updated>2006-11-10T07:25:25.556-08:00</updated><title type='text'>Click Once Deployment</title><content type='html'>It's very handy that Visual Studio had a setup project. You can build a installer application to deploy your applications. That setup project can be configured and edited. New is the posibility to skip this all and use ClickOnce. There is a project tab, you can use to enable ClickOnce. The idea of Click once is to download the application from an URL in a secure environment. The installation is for the logged in user. This also means the you cannot do global things like editing the registry. While starting the Click once application, it's easy to check if a newer release is publish, and if so download them. Also, you have only to download related files, if it's needed. In the propertiesd tab you can set the application files, that have to be installed. They also can be grouped into download groups. Another option are prequisites. These are components that have to be installed before the installation of the real application may starts. These prequisites, if needed, can be downloaded from an URL. &lt;br /&gt;Don't forget to sign the Click once application, because it's only running in secure environments. People have to trust your application. In the security tab, you set the permissions that the application is allowed to do in the secure environment.&lt;br /&gt;Publishing is done by a wizard and not hard to understand.&lt;br /&gt;&lt;br /&gt;To download a download group use&lt;br /&gt;if (!ApplicationDeployment.CurrentDeployment.IsFileGroupDownloaded(([groupname])&lt;br /&gt;{&lt;br /&gt;  ApplicationDeployment.CurrentDeployment.DownloadFileGroup([groupname]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The class, in the example below, makes it possible to manual download an XML file to the executable directory. You can use it to download the application config file.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public abstract class ClickOnceConfiguration&lt;br /&gt;    {&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Retrieves a file from a welknown location and saves it as the configuration file of the application.&lt;br /&gt;        /// &lt;br /&gt;        /// All sections in the file will be refreshed.&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;param name="url"&gt;location to retrieve the configuration file from.&lt;/param&gt;&lt;br /&gt;        /// &lt;param name="fileName"&gt;The name of the file to save as.&lt;/param&gt;&lt;br /&gt;        public static void RetrieveFile(string location, string fileName)&lt;br /&gt;        {&lt;br /&gt;            XmlDocument configurationFile = new XmlDocument();&lt;br /&gt;            configurationFile.Load(location);&lt;br /&gt;            if (configurationFile != null &amp;&amp; !string.IsNullOrEmpty(fileName))&lt;br /&gt;            {&lt;br /&gt;                configurationFile.Save(fileName);&lt;br /&gt;                RefreshSections(configurationFile);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Retrieves a file from a welknown location and saves it as the configuration file of the application.&lt;br /&gt;        /// &lt;br /&gt;        /// All sections in the file will be refreshed.&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;remarks&gt;&lt;br /&gt;        /// The file will be saved as the name of the application that executes this method.&lt;br /&gt;        /// &lt;/remarks&gt;&lt;br /&gt;        /// &lt;param name="location"&gt;Location to retrieve the configuration file from.&lt;/param&gt;&lt;br /&gt;        public static void RetrieveFile(string location)&lt;br /&gt;        {&lt;br /&gt;            string fileName = System.IO.Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, AppDomain.CurrentDomain.SetupInformation.ApplicationName + @".config");&lt;br /&gt;            RetrieveFile(location, fileName);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Refreshes all the named sections in the configuration file.&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;param name="configurationFile"&gt;The xml document that represents the configuration file.&lt;/param&gt;&lt;br /&gt;        private static void RefreshSections(XmlDocument configurationFile)&lt;br /&gt;        {&lt;br /&gt;            if (configurationFile != null)&lt;br /&gt;            {&lt;br /&gt;                // 1. Get All the custom sections.&lt;br /&gt;                XmlNodeList sectionNodesToRefresh = configurationFile.SelectNodes("/configuration/configSections/section");&lt;br /&gt;                if (sectionNodesToRefresh != null &amp;&amp; sectionNodesToRefresh.Count &gt; 0)&lt;br /&gt;                {&lt;br /&gt;                    foreach (XmlNode node in sectionNodesToRefresh)&lt;br /&gt;                    {&lt;br /&gt;                        // Retrieve the names of the custom sections.&lt;br /&gt;                        XmlAttribute name = node.Attributes["name"];&lt;br /&gt;                        if (name != null)&lt;br /&gt;                        {&lt;br /&gt;                            string sectionToRefresh = name.Value;&lt;br /&gt;                            if (!string.IsNullOrEmpty(sectionToRefresh))&lt;br /&gt;                            {&lt;br /&gt;                                ConfigurationManager.RefreshSection(sectionToRefresh);&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;                // 2. Refresh the default sections:&lt;br /&gt;                ConfigurationManager.RefreshSection("appSettings");&lt;br /&gt;                ConfigurationManager.RefreshSection("connectionStrings");&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In the start of the application use this to download it form an URL or local netwok file location.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;ClickOnceConfiguration.RetrieveFile(fileLocation);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Because you can deploy the application also by a local network, you can ask the application if it's network deployed.&lt;br /&gt;&lt;br /&gt;ApplicationDeployment.IsNetworkDeployed&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-116228394716292048?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/116228394716292048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=116228394716292048&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116228394716292048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116228394716292048'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/10/click-once-deployment.html' title='Click Once Deployment'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-116228210919882706</id><published>2006-10-30T23:29:00.000-08:00</published><updated>2006-10-31T01:06:02.390-08:00</updated><title type='text'>Windows Form designer bugs ande Infragistics controls</title><content type='html'>There are lot of designer bugs that mess up the Windows Form. This often happens if the form is not directly derived from baseform. Default a class is of the designer category code, wherease the designer category of a form is 'form'.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[System.ComponentModel.DesignerCategory("code")]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If the designer category is form, a resource file and a designer.cs are automatically created. In the designer class, all form controls are declared and initiated. This code reflects the visual design of the form designer. However, if the design uses not standard issues like resource files or the form derives from a derived form class some design bug issues show up.&lt;br /&gt;&lt;br /&gt;For example, I got this message. FYI: the resource deletes exists, and the application compiles.&lt;br /&gt;&lt;br /&gt;The type 'TNT.Rocs.Properties.Resources' has no property named 'delete'.&lt;br /&gt;Hide Edit&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.Error(IDesignerSerializationManager manager, String exceptionText, String helpLink)&lt;br /&gt;at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression)&lt;br /&gt;at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement)&lt;br /&gt;at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeStatement(IDesignerSerializationManager manager, CodeStatement statement)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I thought installing service pack 1 beta of visual studio 2005 would help. I quess not. The only way to work around is to delete the obj directory and rebuild the solution.&lt;br /&gt;I did'nt try out in VS2005, but if the app.config file is not well XML formed, all controls on all forms lost there initial settings.&lt;br /&gt;&lt;br /&gt;This story is also valid for custom controls. Move custom controls and custom forms to a separate library will ease some pain. But it's often not enough.&lt;br /&gt;&lt;br /&gt;IN my current project, I also use some Infragistics controls (version 2006 vol 2). I really don't like them. They offer a lot of features and properties, which I'll never use. They do not comply the way of working that Microsoft controls have. Let's take the wizard of an UltraGrid. The startbutton is not in the smart tag, but at the control itself. It takes four mega forms with a wizard, to get the grid working. You have the set the database scheme, the appearance, the presets and the feature picker.&lt;br /&gt;And, if I do manual programming of the control, lots of unexpected bugs appear. I cannot add bands(*) dynamically or get the grid in edit mode. May be the last one because getting the grid in edit mode has to do with all the override, global and detail settings, I have to set. And using a MS Access like macro styles used such as "PerformAction(UltraGridAction.EnterEditMode);" are out of date. Why, can't I just call the Edit Method on the grid control itself?&lt;br /&gt;In my previous project, we also used Infragistics. This was an older version. Adding menu items was tough, because some simple text changes smashed the control, somehow.&lt;br /&gt;&lt;br /&gt;*band : One or more related tables joined as one snapshot.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-116228210919882706?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/116228210919882706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=116228210919882706&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116228210919882706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/116228210919882706'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/10/windows-form-designer-bugs-ande.html' title='Windows Form designer bugs ande Infragistics controls'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-115608003417995139</id><published>2006-08-20T06:14:00.000-07:00</published><updated>2006-08-20T06:20:34.180-07:00</updated><title type='text'>Dasblog for 2.0</title><content type='html'>Dasblog is not getting updated anymore. Now there is ASP 2.0. But DasBlog for Net is for .Net 1.1. There is an update for 2.0 made by Andres. He called it Thinkjot. You can download it &lt;a href="http://www.process64.com/ThinkJot/"&gt;here&lt;/a&gt;. I have used the ziplibrary of Ionic Shade called DotNetZiplib and replaced the ISharpZip library. It works fine and the blog site does not use a database. All data is stored in XML files. Good to know if you like let the site get hosted cheap.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-115608003417995139?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/115608003417995139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=115608003417995139&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/115608003417995139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/115608003417995139'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/08/dasblog-for-20.html' title='Dasblog for 2.0'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-115607966911110309</id><published>2006-08-20T06:04:00.000-07:00</published><updated>2006-09-14T02:15:25.583-07:00</updated><title type='text'>Linq &amp; ado.net NExt installation issue</title><content type='html'>I have installed the Ado.Net Next. I found the link on &lt;a href="http://davidhayden.com/blog/dave/archive/2006/08/18/ADONETEntityFrameworkAugustCTP.aspx"&gt; the blog of David Hayden&lt;/a&gt;. If you like to install Ado.NEt Next, you also have to install Linq May CTP. &lt;br /&gt;For the English language everything will install fine. But if you install Linq may CTP on a other language OS, you get security problems. You have to add a user, create owner and power users group. It's sad. Beceause the groupnames already exists in active directy but in your language and not in English. So, if you like to install Linq CTP May install it on English OS only or add the groups manually.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-115607966911110309?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/115607966911110309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=115607966911110309&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/115607966911110309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/115607966911110309'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/08/linq-adonet-next-installation-issue.html' title='Linq &amp; ado.net NExt installation issue'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-115074917526354294</id><published>2006-06-19T10:53:00.000-07:00</published><updated>2006-06-19T13:32:55.346-07:00</updated><title type='text'>WCF</title><content type='html'>Windows Workflow communication. I know the time, when I was a cowboy exploring new lands of remoting. It took lots of time to understand and geting it work how to implement an application. I've seend lands of SOAP and met several binary marchalled objects. Applications were throwing leases to the server. Some of them land in IIS and some were just meant for a service.&lt;br /&gt;Nowaydays, nobody is interested in the complexity of this land. And a state of the union is being prepared. The state is called WCF. It uniformes the way we work with web services, WSE, COM+, Remoting and MSMQ. Objects don't have to be serializable anymore. All class method and members used for transport, just need an attribute. An interface is needed and marked with the ServiceContract attribute. Operations/Methods of the interface must marked with the OperationContract attribute. Attributes with the DataMember attribute. The channel, security and binding settings are settled in the application configuration file. The communication point (street names) are called EndPoints. See it as destination points. Mention that SQL server 2005 also works with EndPoints. A good example of using WCF can be found &lt;a href="http://msdn.microsoft.com/windowsvista/default.aspx?pull=/library/en-us/dnvs05/html/NETremoteWCF.asp"&gt;reading MSDN Vista article.&lt;/a&gt;&lt;br /&gt;But for real examles visit the &lt;a href="http://wcf.netfx3.com/content/resources.aspx"&gt;WCF site&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;br /&gt;&lt;tbody&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;&lt;br /&gt;A book about software factories.&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/7872/820/1600/BookCover.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/7872/820/320/BookCover.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/Wiki/View.aspx?ProjectName=ISpySoft"&gt;Visit CodePlex ISpySoft for more info&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A book about Team System&lt;br /&gt;&lt;img src="http://images.amazon.com/images/P/1590594606.01._AA240_SCLZZZZZZZ_V52629803_.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/1590594606/002-6268243-5588016?v=glance&amp;amp;n=283155"&gt;Buy it at Amazon&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-115074917526354294?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/115074917526354294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=115074917526354294&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/115074917526354294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/115074917526354294'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/06/wcf.html' title='WCF'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-115072365569142386</id><published>2006-06-19T06:20:00.000-07:00</published><updated>2006-06-19T06:28:03.133-07:00</updated><title type='text'>ADO.Ne(x)t 3.0 (LINQ)</title><content type='html'>Microsoft’s word about WinFX's final name is out. It will be named Framework 3.0 as expected. Its release date is expected to be in 2007 (VS Orca's). I am not totally sure of Ado.Net 3.0 be part of it. But I think it is. There was during the Teched 2006 some confusion about Ado.Net Next and Linq. What is the difference? Two projects? And which will be part of the new release?&lt;br /&gt;&lt;br /&gt;Linq's purpose is hiding the SQL and XML from object programming in a transparent uniform way. With a help tool called SQLMetal a mapping between database and objects can be made. SQLMetal will create the business objects and map this to the database tables/fields for you. With the help of Linq, data can be queried and updated thought the business objects almost automatically. The Data Context object, where all business objects derive from, will keep track of all changes. Changes can be undone and be part of a transaction. With DLinq, database Linq, even stored procedures can be used. Lot of information can be found for this at &lt;a href="http://weblogs.asp.net/scottgu/archive/2006/06/18/DLINQ-with-Stored-Procedures.aspx"&gt;ScottGu's blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you watch the video post at &lt;a href="http://channel9.msdn.com/Showpost.aspx?postid=202138"&gt;channel 9&lt;/a&gt;, you can listen to Anders Hejlsberg and Sam Druker talking about Ado.Net Next technology. After this, you can get confused. But hello they still talk about Linq. And some addition which is called the Entity Data Model (EDM). This adds support for complex types and inheritance. Which were mentioned at channel 9.&lt;br /&gt;Complex types are reference types like address. This type consist of more then one property. In the mapping file, an AssocationSetMapping can be made. Then it's possible to query the universal object, without joining in SQL the foreign key related tables together. So customer and customer address is just one business object. With one 'code' statement, the related table objects can be queried. In the background, the two table will be queried and updated.&lt;br /&gt;What EDM does, is not spectacular. But on the other hand, it makes life a little bit simpler. EDM is capable of making a view. Read much more at &lt;a href="http://msdn.microsoft.com/data/"&gt;http://msdn.microsoft.com/data/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;One more thing. The verb 'Object space' is back. Relations between objects are stored in an object space. This enables querying though different kind of objects related to each other. There is no need to give extra info. Just once in the mapping file.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ADO 3.o/LINQ benefits&lt;/b&gt;&lt;br /&gt;- &lt;i&gt;Data in All Tiers&lt;/i&gt;. As Example. DLinq can be used in the Data Server Tier or Middle tier to communicate with the database. Where XML can be used in the middle tier and client tier as data source. And you can use binary data transport mechanism to transport the data between the layers. Support for Mobile devices is of course included.&lt;br /&gt;- &lt;i&gt;All types of Data&lt;/i&gt;. They mean that every data source can be used. Of course, not all will be part of the released standard. It says: Adopting your data source is made easy.&lt;br /&gt;- &lt;i&gt;Uniform Data Access&lt;/i&gt;. To get or update data from a data source can be done in one unified way. There is no difference in usage for XML, Delimited Text File or SQL Database.&lt;br /&gt;- &lt;i&gt;End-to-End Business Insight&lt;/i&gt; Microsoft’s creates again Lego, not a static product. You can kneed anything you want with the business objects, with the please of the ease of Linq.&lt;br /&gt;- &lt;i&gt;Ubiquitous Data Services&lt;/i&gt; By transport between layers, security, synchronization, and (custom) types of serialization are still possible.&lt;br /&gt;Rich “Abilities”. Keywords: Availability, secured and scalable.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Negative points&lt;/b&gt;&lt;br /&gt;Personally, I do not know what kind of Network bandwidth you will need to use it. That's the negative point here, I am sceptical about. Each business object call will create one or several queries through all layers. It does not use smart concepts for performance. It will not use a cache mechanism for static data. And what about paging? Is it supported? Can I just say? Get the first hundred products. Get Next Result?.&lt;br /&gt;A second note, that E/R mapping is used, where often O/R mapping is demanded. O/R mapping hides the technical ‘ID’ fields. It’s not part of the business. With O/R mapping, navigation between objects in code is more easy.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;It's very good. I cannot compete with Microsoft. Every time they surprise me, making my life a little bit better. However, in all big projects, there will be many complains about performance and scalability. Linq is therefore no solution. It does not smart retrieval and caching of the data through the layers. I think, Linq will make this even more complex to achieve. I am wondering how to achieve this?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-115072365569142386?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/115072365569142386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=115072365569142386&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/115072365569142386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/115072365569142386'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/06/adonext-30-linq.html' title='ADO.Ne(x)t 3.0 (LINQ)'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-115035409868672289</id><published>2006-06-14T23:07:00.000-07:00</published><updated>2006-06-14T23:49:53.166-07:00</updated><title type='text'>Installation of Team Foundation Server on a VPC</title><content type='html'>I succeeded in installation of the Team Foundation Server on a Virtual PC. Although there is a good &lt;a href="go.microsoft.com/fwlink/?liTnkid=40042"&gt;installation guide&lt;/a&gt; the installation is not as easy at it seems. Tim Erickson succeeded in february already to &lt;a href="http://blogs.claritycon.com/blogs/tim_erickson/archive/2006/02/13/207.aspx"&gt;install Team Foundation Server on a VPC&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;I had problems with deïnstalling Frontpage Service Extensions. From the managment console of Internet Information Services, I tried to uninstall those frontpage service extensions. Doing it the way Microsoft suggested, I ended up with a NT login Window. I could't pass it. &lt;br /&gt;&lt;br /&gt;To remove FPSE. I found the following solution&lt;br /&gt;Go the the program files directory and then to subdirectory "Microsoft Shared\Web server extensions\50\bin".&lt;br /&gt;&lt;br /&gt;eg.&lt;br /&gt;C:\Program Files\Common Files\Microsoft Shared\web server extensions\50\bin:&lt;br /&gt;&lt;br /&gt;Use the OWSADM tool to uninstaal FSPE&lt;br /&gt;Usage: owsadm -o uninstall -p 80 &lt;br /&gt;where 80 is a port number.&lt;br /&gt;&lt;br /&gt;After having installed SQL Server 2005 install also SQLServerKB\AS2005-KB914595-x86-ENU.exe&lt;br /&gt;Sharepoint Service Pack 2 is also on the TFS DVD media in the root directory. It is called 'stsv2.exe'&lt;br /&gt;&lt;br /&gt;I had some problems, because I forgot to do some updates. When I tried to install Team Foundation Server, the software checked possible problems. One of them pointed that ASP.NET 2.0 QFE not was installed. So, I installed KB913393, found on the Team Foundation DVD media.&lt;br /&gt;&lt;br /&gt;After having installed all the software, I still was not able to connect to TFS Server on the VPC. I got the connection error &lt;a href="msdn.microsoft.com/vstudio/teamsystem/tfsreadme.aspx"&gt;HTTP status 403: TF53011: domain\user is not a licensed user&lt;/a&gt;. As solution, I installed therefore Team Explorter on the VPC. And add users with help of an atricle found called &lt;a href="http://blogs.msdn.com/vstsue/articles/556043.aspx"&gt;Visual Studio Team System User Education, How to: Add Users for Team Foundation Server Workgroup Edition&lt;/a&gt;. I started Team explorter at my VPC. And then, I could add the right NT users to the licensed user group. And voila connection from my PC to the VPC with TFS worked.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-115035409868672289?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/115035409868672289/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=115035409868672289&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/115035409868672289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/115035409868672289'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/06/installation-of-team-foundation-server.html' title='Installation of Team Foundation Server on a VPC'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114916462062913372</id><published>2006-06-01T04:38:00.000-07:00</published><updated>2006-06-01T05:23:40.660-07:00</updated><title type='text'>Query pattern</title><content type='html'>I've created my own way to communicate with databases. Instead of injecting direct SQL, I decided to create two classes which has all the elements of an sql statement. The first class is the query class and the second class is the wehre clause class. This solution it possible to have that syntax highlighting for SQL statements. But there is more. It makes quering dynamic. I can mannualy add a where statement to an existing statement. And this where statement can contain a dynamic parameter. I found out that .NET 2.0 has a factory pattern for connections, commands, parameters and for database types. So, I can database independent add such a parameter. With real command parameters, I can prevend SQL injections and also serialize different types of parameters like datetime and images correctly.&lt;br /&gt;&lt;br /&gt;In the query class this is what makes SQL&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private string GetSQLStatement()&lt;br /&gt;{&lt;br /&gt;switch (_queryType)&lt;br /&gt;{&lt;br /&gt;case SQLQueryType.Select:&lt;br /&gt;_sqlStatement = "Select " + _strSelect + " From " + _strFrom;&lt;br /&gt;if (_strJoin.Length &gt; 0) _sqlStatement += " " + _strJoin;&lt;br /&gt;if (_strWhere.Length &gt; 0)&lt;br /&gt;{&lt;br /&gt;_sqlStatement += " Where " + _strWhere;&lt;br /&gt;FinishWhereScopes();&lt;br /&gt;}&lt;br /&gt;if (_strSort.Length &gt; 0) _sqlStatement += " Order by " + _strSort;&lt;br /&gt;break;&lt;br /&gt;case SQLQueryType.Delete:&lt;br /&gt;_sqlStatement = "Delete From " + _strFrom;&lt;br /&gt;if (_strWhere.Length &gt; 0)&lt;br /&gt;{&lt;br /&gt;_sqlStatement += " Where " + _strWhere;&lt;br /&gt;FinishWhereScopes();&lt;br /&gt;}&lt;br /&gt;break;&lt;br /&gt;case SQLQueryType.Insert:&lt;br /&gt;_sqlStatement = "Insert Into " + _strFrom + " (" + _strSelect + ")";&lt;br /&gt;_sqlStatement += "Values (" + _strValues + ")";&lt;br /&gt;if (_strWhere.Length &gt; 0)&lt;br /&gt;{&lt;br /&gt;_sqlStatement += " Where " + _strWhere;&lt;br /&gt;FinishWhereScopes();&lt;br /&gt;}&lt;br /&gt;break;&lt;br /&gt;case SQLQueryType.Update:&lt;br /&gt;_sqlStatement = "Update " + _strFrom;&lt;br /&gt;_sqlStatement += String.Join(",", (string[])arrSetValues.ToArray());&lt;br /&gt;if (_strWhere.Length &gt; 0)&lt;br /&gt;{&lt;br /&gt;_sqlStatement += " Where " + _strWhere;&lt;br /&gt;FinishWhereScopes();&lt;br /&gt;}&lt;br /&gt;break;&lt;br /&gt;}&lt;br /&gt;return _sqlStatement;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In my SQLWhereOperater class, I have this piece of code to parameter the query&lt;br /&gt;The function adds the parameter. With help of my mapping class, I know which SQL Type is used. A reference to the query object is needed to add the parameter directly to the query object. The where statement however has to be added manually. This is due to making the where part an AND or OR clause condition.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public string TypeValue(DatabaseFieldInfo mapping, int index, object value)&lt;br /&gt;{&lt;br /&gt;string parameterName =String.Format("@{0}" , mapping.Field);&lt;br /&gt;if (index != -1)&lt;br /&gt;{&lt;br /&gt;parameterName += index.ToString();&lt;br /&gt;}&lt;br /&gt;if (!_query.DatabaseParameters.Contains(mapping.Field))&lt;br /&gt;{&lt;br /&gt;DbParameter parameter = _query.DatabaseCommand.CreateParameter();&lt;br /&gt;parameter.Direction = System.Data.ParameterDirection.Input;&lt;br /&gt;parameter.ParameterName = parameterName;&lt;br /&gt;parameter.DbType = mapping.DatabaseType;&lt;br /&gt;parameter.Size = mapping.Size;&lt;br /&gt;parameter.Value = value;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;_query.DatabaseParameters.Add(parameter);&lt;br /&gt;}&lt;br /&gt;return parameterName;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public virtual string Equal(DatabaseFieldInfo mapping,object value)&lt;br /&gt;{&lt;br /&gt;_whereClause = mapping.Field + "=" + TypeValue(mapping, value);&lt;br /&gt;return _whereClause;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This is what a general query looks like in my application. I start a query factory. Which it database independend. I use therefore the factory pattern of ADO.Net 2.0.&lt;br /&gt;In the example, I add a select query with all mapped fields. And add the table name from the mapping class. If there is a parent object, this data should be filtered by the parent key.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;SQLQuery q = SQLQuery.QueryFactory(Connection);&lt;br /&gt;q.Select(AllFields);&lt;br /&gt;q.From(_fieldmappings.TableName);&lt;br /&gt;if (Parent != null)&lt;br /&gt;{&lt;br /&gt; _fieldmappings.SqlMapForeignKeys(q, Parent);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Adding an extra where statement is a little more complicated, but still easy to read.&lt;br /&gt;I still create a query, add an operator. Give database field information to the where statement. The finishedgoodsflag is not a property in my object model!!!. So, I cannot use the mapping class instance. But, I have a DatabaseFieldInfo class which can do the job. And for mapped properties, this class is also used. It just contains the name, type, size and precision of the database field. The mapping class contains also information about the class and the properties. The mapping class also has knowledge about primary, foreign and parent keys. &lt;br /&gt;&lt;br /&gt;I add the where equal statement to the where operator class and add the whereoperater as an and statement to the SQL where clause.&lt;br /&gt;&lt;br /&gt;The sql statement made looks like&lt;br /&gt;Select Name, ListPrice ....&lt;br /&gt;from  [adventureworks].[production].[product]&lt;br /&gt;where productsubcategoyId=12&lt;br /&gt;and finishedgoodflag=1&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;FinishedProducts collection = new FinishedProducts();&lt;br /&gt;collection.ConnectionName = "AdventureWorks";&lt;br /&gt;collection.SetParent(productSubCategory);&lt;br /&gt;SQLQuery query = collection.GetAllDataQuery();&lt;br /&gt;SQLWhereOperator expression = query.NewWhereOperator();&lt;br /&gt;DatabaseFieldInfo fieldFinishedGoodInfo =new DatabaseFieldInfo(DbType.Boolean, "FinishedGoodsFlag");  &lt;br /&gt;expression.Equal(fieldFinishedGoodInfo, 1);&lt;br /&gt;query.Where(SQLWhereAndOr.And, expression);   &lt;br /&gt;collection.ReadCollectionFromCommand(query.GetCommand); &lt;br /&gt;return collection;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;For your information, I have used inheriance on the product class.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114916462062913372?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114916462062913372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114916462062913372&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114916462062913372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114916462062913372'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/06/query-pattern.html' title='Query pattern'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114910767895633468</id><published>2006-05-31T10:42:00.000-07:00</published><updated>2006-06-01T05:26:17.336-07:00</updated><title type='text'>DLinq OR/M or not?</title><content type='html'>&lt;b&gt;SQL in Code&lt;/b&gt;&lt;br /&gt;It's not beautifull in having SQL statements in the code. A good manner is to change SQL to class based queries. The &lt;a href="http://msdn.microsoft.com/data/ref/linq/"&gt;Linq&lt;/a&gt; project is just one of them. The good side of the Linq is transparancy in doing queries. DLinq or XLInq will communicatie with ad hoq queries and DLinq also with procedures. DLinq is made for relational databases and XLinq for XML files. Modification can be saved at once.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Mapping entities with objects&lt;/b&gt;&lt;br /&gt;Also it's a good idea to automate the link between database and business objects. Dlinq is supporting this. Mapping objects to database objects can be done with attribute mapping or XML mapping. The first one uses reflection, which will reduce the performance a little bit.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Mapping entities to object with utility SQL Metal&lt;/b&gt;&lt;br /&gt;Writing and executing DLinq queries requires a class that implements the 'DataContext' interface to map an relational tables of SQL Server to LINQ objects. The DataContext class also translates LINQ query code and object modifications into SQL statements for retrieving and updating data. The SqlMetal.exe utility is used to create a strongly-typed DataContext class file from an SQL Server 2000 or 2005 database's metadata.&lt;br /&gt;&lt;br /&gt;sqlmetal [options] [input]&lt;br /&gt;options:&lt;br /&gt;/server:&lt;database&gt;&lt;br /&gt;/database:&lt;database&gt;&lt;br /&gt;/user:&lt;login&gt;&lt;br /&gt;/password:&lt;login&gt;&lt;br /&gt;/views extract database views --Include views&lt;br /&gt;/xml[:output as xml to file] -- Mapping file as XML&lt;br /&gt;/code[:output as code to file]&lt;br /&gt;/language:xxx for code (C# or VB)&lt;br /&gt;/namespace:&lt;Class namespace&gt;&lt;br /&gt;/pluralize auto or table names&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entity based or Object based approach?&lt;/b&gt;&lt;br /&gt;There are also some minor with Linq. First of all it has it's relational way. And it means that business objects are based on the entity relational model of the database. But it should be the other way around. If the business needs are specified there will be a class diagram first. Before UML was known, the ER-model was the first one. But no it's another way around, we should also think the other way around. &lt;br /&gt;Another reason is that with object based approach the complexity of relations is hidden and the object tree can be considered as one piece. In entity related aproach, each object is loosely connected with foreign keys and related data has to be filtered manually.&lt;br /&gt;&lt;br /&gt;Example DLinq&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Table&lt;customer&gt; Customers = db.GetTable&lt;customer&gt;();&lt;br /&gt;Table&lt;customer&gt; Customers = db.GetTable&lt;customer&gt;();&lt;br /&gt;&lt;br /&gt;Selecting objects is like doing a select statement in code&lt;br /&gt;var custs =         from c in Customers&lt;br /&gt;                    where c.CompanyName.StartsWith("a")&lt;br /&gt;                    select c;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This will be translated into SQL Server query&lt;br /&gt;&lt;code&gt;&lt;br /&gt;exec sp_executesql N'SELECT [t0].[Address], [t0].[City], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Country], [t0].[CustomerID], [t0].[Fax], [t0].[Phone], [t0].[PostalCode], [t0].[Region]&lt;br /&gt;FROM [Customers] AS [t0]&lt;br /&gt;WHERE [t0].[CompanyName] LIKE @p0', N'@p0 nvarchar(2)', @p0 = N'a%'&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;a href="http://unboxedsolutions.com/sean/archive/2005/09/18/745.aspx"&gt;source&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Replacement for OR/M&lt;/b&gt;&lt;br /&gt;Also Linq only supports SQL server at the moment. The team will make a provider model. This will enable Oracle and other databases to user Dlinq.&lt;br /&gt;DLinq is probably slower then tradional queries. I haven't figured it out yet, but there is no intelligence with it. And how will it work in multi-user environments or performance critical applications? It there a caching mechanism. Can it be serialized, extended with business rules etc.. And most of all, is it an allround Business Object layer?&lt;br /&gt;You can draw your own colclusion with the information, I found at &lt;a href="http://www.theserverside.net/news/thread.tss?thread_id=36866"&gt;The Server Site&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;It all looks very nice. And as bonus, Microsoft will add it to the framework. But it's not the OR/M mapper most people will expect. It's just an entity to object translater which is capable to persist and retrieve data.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114910767895633468?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114910767895633468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114910767895633468&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114910767895633468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114910767895633468'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/05/dlinq-orm-or-not.html' title='DLinq OR/M or not?'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114698685743904555</id><published>2006-05-07T00:19:00.000-07:00</published><updated>2006-05-13T02:19:12.436-07:00</updated><title type='text'>Suppress debug assertion dialogs</title><content type='html'>For the build, it was needed that no popup's showed. The build server tested our unit tests. If unit test failed, we should look after the code. The server couldn't handle the popup's and then a timeout causes a broken build. So we were forced to remove those debug.asserts. Now, I found on the internet interesting code, which would saved our day. This code, skips the prompted debug assert dialog. But the build will still break the unit test triggering the assert.&lt;br /&gt;&lt;br /&gt;foreach (System.Diagnostics.TraceListener listener in System.Diagnostics.Debug.Listeners)&lt;br /&gt;{&lt;br /&gt;  System.Diagnostics.DefaultTraceListener defaultListener = listener as System.Diagnostics.DefaultTraceListener;&lt;br /&gt;  if (defaultListener != null &amp;&amp; !System.Diagnostics.Debugger.IsAttached)&lt;br /&gt;  {&lt;br /&gt;    defaultListener.AssertUiEnabled = false;&lt;br /&gt;  }&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114698685743904555?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114698685743904555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114698685743904555&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114698685743904555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114698685743904555'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/05/suppress-debug-assertion-dialogs.html' title='Suppress debug assertion dialogs'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114698532275997933</id><published>2006-05-07T00:01:00.000-07:00</published><updated>2006-05-07T00:02:02.770-07:00</updated><title type='text'>O/R Mapping IReadCollection interface</title><content type='html'>In the code class I implement the IReadCollection interface. It's purpose is to list all database fields of the code class. I totally made description and modified optional fields.&lt;br /&gt;&lt;br /&gt;public List GetFields()&lt;br /&gt;{&lt;br /&gt;List list = new List();&lt;br /&gt;list.Add(_codeField);&lt;br /&gt;list.Add(_nameField);&lt;br /&gt;if (this.HasDescription) &lt;br /&gt;list.Add(_descriptionField);&lt;br /&gt;if (this.HasModifiedDate)&lt;br /&gt;list.Add(_modifiedDateField);&lt;br /&gt;return list; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;The read collection determines the ordinal code of the fields first. This is clever. Because ordinal reading is a bit faster then reading data using names. Beceause, I know the field types. I can create an instance of a new code class element and fetch the data into these elements. At last, I add the element to the CodeClassCollection (Generic.Dictionary).&lt;br /&gt;&lt;br /&gt;public void ReadCollection(DbDataReader reader)&lt;br /&gt;{&lt;br /&gt;DetermineOrdinals(reader);&lt;br /&gt;while (reader.Read())&lt;br /&gt;{&lt;br /&gt;TCodeClass codeClass = GetNewInstance();&lt;br /&gt;codeClass.Code = reader.GetString(ordinalCode);&lt;br /&gt;codeClass.Name = reader.GetString(ordinalName);&lt;br /&gt;if (HasDescription)&lt;br /&gt;codeClass.Description = reader.GetString(ordinalDescription);&lt;br /&gt;if (HasModifiedDate)&lt;br /&gt;codeClass.ModifiedDate = reader.GetDateTime(ordinalModifiedDate);&lt;br /&gt;Add(codeClass.Code, codeClass);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Also, determine the ordinals is a piece of cake. I let the use of the class set the name of the database field and ask the reader, what the corresponding ordinal is.&lt;br /&gt;&lt;br /&gt;/// &lt;br /&gt;/// Determine ordinals code, namde, description and modified date&lt;br /&gt;/// &lt;br /&gt;/// &lt;br /&gt;public virtual void DetermineOrdinals(DbDataReader reader)&lt;br /&gt;{&lt;br /&gt;ordinalCode = reader.GetOrdinal(_codeField );&lt;br /&gt;ordinalName = reader.GetOrdinal(_nameField );&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;if (HasDescription)&lt;br /&gt;ordinalDescription = reader.GetOrdinal(_descriptionField );&lt;br /&gt;}&lt;br /&gt;catch (IndexOutOfRangeException)&lt;br /&gt;{&lt;br /&gt;_hasDescription = false;&lt;br /&gt;}&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;if (HasModifiedDate)&lt;br /&gt;ordinalModifiedDate = reader.GetOrdinal(_modifiedDateField );&lt;br /&gt;}&lt;br /&gt;catch (IndexOutOfRangeException)&lt;br /&gt;{&lt;br /&gt;_hasModifiedDate = false; &lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Although determine ordinals for these small list's will not make a performance difference, this is the fastest way to accomplish such a task.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114698532275997933?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114698532275997933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114698532275997933&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114698532275997933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114698532275997933'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/05/or-mapping-ireadcollection-interface.html' title='O/R Mapping IReadCollection interface'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114698459335999475</id><published>2006-05-06T23:20:00.000-07:00</published><updated>2006-05-06T23:49:53.373-07:00</updated><title type='text'>O/R Mapping Reading the codeclasses</title><content type='html'>A code class is a simple class with not much records (&lt;200). The code class contains at least two fields: code and name. And at most four fields. This includes description an modified date. In a project there can be +/- 24 code classes. So the size of all data of the code classes is to oversee. Also, the data of these classes can be very static. For extra, I include also the enumerations. This classes are static. Although a number and a code definition would be sufficient. I would like to have a more user friendly description for the user. And also be able to query the database knowing what the enum value means. Data of enum classes are static by default. To store this data, I will use a singleton pattern or web cache technique, to keep them in memory.&lt;br /&gt;&lt;br /&gt;I thought why loading this data with +/- 24 databases commands x several access times in your application? So, I queued a todo list with 'select statements' for each object on the list. A special CodeClass list handles the retrieval of the items.&lt;br /&gt;&lt;br /&gt;I store a code class or enumerable in a private class containing the code class and it's database table name. And add them to a queue. The IRecordCollection interface has to obligations: GetFields() and ReadCollection(DBDataReader). The first one I use to create a sql select command. The second one, I Use to activate the code class reader.&lt;br /&gt;&lt;br /&gt; /// &lt;summary&gt;&lt;br /&gt;        /// An enumerable class is a class containing an enumerable code class &lt;br /&gt;        /// This codeclass has a corresponding enum facility&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        /// &lt;param name="enumerable"&gt;Enumerable class&lt;/param&gt;&lt;br /&gt;        /// &lt;param name="table"&gt;Database Table&lt;/param&gt;&lt;br /&gt;        public void AddEnumerableClass(IReadCollection enumerable, string table)&lt;br /&gt;        {&lt;br /&gt;            CodeClassMapping mapping = new CodeClassMapping(enumerable,table);&lt;br /&gt;            _queue.Enqueue(mapping);&lt;br /&gt;        }        &lt;br /&gt;&lt;br /&gt;Because the queue is a first in first out system, I know exactly which select statement was executed first and which one the last. I query all the select sql statement at one time. then, I deque the codeclassmapping class and read it's collection. The nextresult command will forward to the next datareader. At last close the connection and clean up unfinished business. I forgot that exception, which will not occur.&lt;br /&gt;&lt;br /&gt;   public void ReadAllWithSql()&lt;br /&gt;        {            &lt;br /&gt;            DbCommand command = _connection.CreateCommand();&lt;br /&gt;            command.CommandType = CommandType.Text;&lt;br /&gt;            command.CommandText = GetAll();&lt;br /&gt;            _connection.Open();&lt;br /&gt;            DbDataReader reader = command.ExecuteReader();&lt;br /&gt;            while (_queue.Count &gt; 0)&lt;br /&gt;            {&lt;br /&gt;                CodeClassMapping codeClassMapping = _queue.Dequeue();&lt;br /&gt;                codeClassMapping.IReadCollectionObject.ReadCollection(reader);&lt;br /&gt;                reader.NextResult();&lt;br /&gt;            }&lt;br /&gt;            _connection.Close();&lt;br /&gt;            _connection = null;&lt;br /&gt;            _queue.Clear(); //I meant this&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The following code looks strange. Iterate an sql statement and get it's sql. Add this as a new string line. But this create just one sql script for them all.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        public string GetAll()&lt;br /&gt;        {&lt;br /&gt;            StringBuilder builder = new StringBuilder();&lt;br /&gt;            foreach (string sql in GetNextSql())&lt;br /&gt;            {&lt;br /&gt;                builder.AppendLine(sql);&lt;br /&gt;            }&lt;br /&gt;            return builder.ToString();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;The getnextsql does a for each loop on the codemapping class in the queue. The GetSelectSql() returns just one sql select statement.&lt;br /&gt;&lt;br /&gt;public IEnumerable&lt;string&gt; GetNextSql()&lt;br /&gt;        {&lt;br /&gt;            foreach (CodeClassMapping map in _queue)&lt;br /&gt;            {&lt;br /&gt;                yield return map.GetSelectSql();&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        }&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114698459335999475?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114698459335999475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114698459335999475&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114698459335999475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114698459335999475'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/05/or-mapping-reading-codeclasses.html' title='O/R Mapping Reading the codeclasses'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114544451407320186</id><published>2006-04-19T03:51:00.000-07:00</published><updated>2006-05-06T05:20:34.026-07:00</updated><title type='text'>O/R Mapping</title><content type='html'>There are several techniques for reading data from the database and to persist this in a business object. I'll discuss some techniques.&lt;br /&gt;&lt;br /&gt;Techniquest to read data from table to be used by businessobjects:&lt;br /&gt;- Table reader. Reads a table with the (sql)reader using a command object (query or stored procedure)&lt;br /&gt;- Child Table Reader. Same, but a parent tablekey as parameter is used&lt;br /&gt;- Tree reader. Reads from a root object and obtain children object. This can be accomplished by using multple readers or one XML reader. I prefer the last one.&lt;br /&gt;&lt;br /&gt;Using queries or stored procedures?&lt;br /&gt;There is no difference in performance. Although procedures are compiled, the compile time is just a minor issue. Queries must not be programmed in text staments. It makes code unreadable and the re-use is also bad. concluded, I use default a query processor. But for some cases, if procedures are required, I also build support for that option.&lt;br /&gt;&lt;br /&gt;Table readers are used for simple tables or tables with a small child depth. Like code claesses. Child table readers are used to read child object the same way. Tree readers are used to read parent-child in one request. This will boost performance. To make code less complex, I'll use XML. Also this makes webservice support more easily.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114544451407320186?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114544451407320186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114544451407320186&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114544451407320186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114544451407320186'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/04/or-mapping_19.html' title='O/R Mapping'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114495032150318666</id><published>2006-04-13T10:37:00.000-07:00</published><updated>2006-04-19T03:51:34.093-07:00</updated><title type='text'>O/R Mapper Code classes</title><content type='html'>I've created 3 seperated classes for different needs&lt;br /&gt;- CodeClass (Code, Name class), HasDescription property false&lt;br /&gt;- CodeClass (Code, Name, Description)&lt;br /&gt;- Enumerable class (Enum int, Name) + Enum&lt;br /&gt;&lt;br /&gt;The first two classes will fullfill most needs. Version and Timestamp are not included. This is only needed in the business classes. These classes are used for reading and using, not for persisting. &lt;br /&gt;&lt;br /&gt;The enumerable is used for database consistent. The enum is used in the application. The data is used for database purposes. For display the enumerable class can also be used to retrieve the name of the enumerable. Remember an Enum is just a sequence of named values. But the names are programmatic and not always displayable.&lt;br /&gt;&lt;br /&gt;I plan also to adapt de last modified date. This date is used in the Adventure works database (example database from Microsoft) in each code class. This option is only for the extended codeclass.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114495032150318666?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114495032150318666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114495032150318666&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114495032150318666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114495032150318666'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/04/or-mapper-code-classes.html' title='O/R Mapper Code classes'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114494981978208187</id><published>2006-04-13T10:25:00.000-07:00</published><updated>2006-04-13T10:36:59.793-07:00</updated><title type='text'>O/R Mapper 2 Parent object</title><content type='html'>Lothka uses root object and child object to differ a parent object and a child object. Child object must be marked as childs. It's more complicated if instances of a particlar class can be both at runtime. In my opion a root object is a object without a parent. It's handy to know a class it's parent (if avaiwlable). mostly because the child database table needs the key of the parent.&lt;br /&gt;&lt;br /&gt;Table ProductCateogry&lt;br /&gt;ProductCateogryId&lt;br /&gt;Description&lt;br /&gt;&lt;br /&gt;Table Product&lt;br /&gt;Product ID&lt;br /&gt;ProductCategoryId (in this case parent, the parent ID is needed)&lt;br /&gt;Description&lt;br /&gt;&lt;br /&gt;The item class as well the collection class have this function and as constructor. &lt;br /&gt;&lt;br /&gt;public void SetParent(object parent)&lt;br /&gt;        {&lt;br /&gt;            if (_parent != null)&lt;br /&gt;            {&lt;br /&gt;                _parent = parent;&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                throw new Exception(Resources.ParentAlreadySet);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;Nice is, that resource files can be used directly in 2.0. Add a string to a resource file and you can directly use it. Usages of enumeration classes or methods like resource.getstring(resource.key) are not needed anymore.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114494981978208187?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114494981978208187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114494981978208187&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114494981978208187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114494981978208187'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/04/or-mapper-2-parent-object.html' title='O/R Mapper 2 Parent object'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114494913794276514</id><published>2006-04-13T10:18:00.000-07:00</published><updated>2006-04-13T10:25:37.973-07:00</updated><title type='text'>O/R Mapping</title><content type='html'>There are lot of O/R mappings out there. But there is not a Visual Studio 2005 one. Lothka has released a new version. But it's not fitting myy needs. So I started to write my own. First of al I use lo of Generics. In the framework a collection should refer to it's item. Collection are derived from Dictionary. The key cannot be given in the collection. This is determined by the item. So the item should have a function to return it's primary key. The collection is responsible for reading the data from the database. The factory pattern of ADO is used. So, there is no need to store database specific information in the collection. Reading value from the database will be realised with the following function&lt;br /&gt;&lt;br /&gt;  public void ReadCollection(DbDataReader reader)&lt;br /&gt;        {      &lt;br /&gt; &lt;br /&gt;&lt;br /&gt;            Dictionary&lt;int,string&gt; list  = DetermineOrdinals(reader);&lt;br /&gt;            if (_fieldList == null)&lt;br /&gt;            {&lt;br /&gt;                BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;                &lt;br /&gt;                _fieldList = new List&lt;FieldInfo&gt;();&lt;br /&gt;                foreach (KeyValuePair&lt;int, string&gt; entry in list)&lt;br /&gt;                {&lt;br /&gt;                    _fieldList.Add(typeof(TReferenceClass).GetField(entry.Value, flags));&lt;br /&gt;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            while (reader.Read())&lt;br /&gt;            {&lt;br /&gt;&lt;br /&gt;                  &lt;br /&gt;                  TReferenceClass item = new TReferenceClass(); &lt;br /&gt;                  int val=0;&lt;br /&gt;                  foreach (KeyValuePair&lt;int,string&gt; entry in list)&lt;br /&gt;                  {&lt;br /&gt;                      _fieldList[val++].SetValue(item,reader.GetValue(entry.Key ));  &lt;br /&gt;                  }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;First of al the fields will be identified with the ordinals. This is a special function and runned once. _fieldlist is a static variable. Why doing it twice?&lt;br /&gt;The dictionary of fieldlist contains the ordinal and the value. Just in determine ordinals names of database fields and the item class will be mapped.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114494913794276514?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114494913794276514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114494913794276514&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114494913794276514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114494913794276514'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/04/or-mapping.html' title='O/R Mapping'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114404751002391417</id><published>2006-04-02T23:29:00.000-07:00</published><updated>2006-04-03T02:16:15.933-07:00</updated><title type='text'>Windows form cache</title><content type='html'>Why using cache?&lt;br /&gt;- Performance. Having data sotred in memory is a lot quicker.&lt;br /&gt;- Scalability. Using the network, calling the database to get the information cost often more time then storing data locally. Less use of the server.&lt;br /&gt;- Availability. Makes the application less dependent on the server avaibility.&lt;br /&gt;- This is a good solution to store some static data.&lt;br /&gt;&lt;br /&gt;In Windows there is no such thing as a cache object. There is a very good &lt;a href="http://www.codeproject.com/csharp/cacheinwinformapps.asp"&gt;alternative&lt;/a&gt; to use the web cache in a winform application. This option uses the system.web en system.web.cache namespace. &lt;br /&gt;Of course the Enterprise library can also be used. This solution also makes it possible to save the cache to disk. Make the cached items serializable and derive a class from the BaseBackingStore. Store the items in this Backing Store.&lt;br /&gt;An other way is to use an hashtable used in a singleton pattern class. But this option has less capabilities.&lt;br /&gt;&lt;br /&gt;Using the enterprise library to cache &lt;br /&gt;&lt;br /&gt;Default cache&lt;br /&gt;CacheManager defaultCache = CacheManager.GetCacheManager(); &lt;br /&gt;defaultCache.Add(“item1”, myObject); &lt;br /&gt;Specific cache&lt;br /&gt;CacheManager specialCache = CacheManager.GetCacheManager(“Special”); &lt;br /&gt;specialCache.Add(“codeTableItem”, codeTableObject); &lt;br /&gt;&lt;br /&gt;That the enterprise library looks like the system.web.cache is not spectaculair. Microsoft and Avanade exchange and use each others knowledge. This means the peaces of the Enterprise library will be picked up by Microsoft and assimilated in the new Visual Studio products.&lt;br /&gt;&lt;br /&gt;DateTime refreshTime = new DateTime(2006, 4, 21, 2, 12, 0);//yyyy,m,d,hour,sec,mills&lt;br /&gt;AbsoluteTime expireTime = new AbsoluteTime(refreshTime);   &lt;br /&gt;defaultCache.Add("flushableItem", "value of item", CacheItemPriority.Normal,&lt;br /&gt;                                      null, expireTime);&lt;br /&gt;&lt;br /&gt;The absolute time, the sliding time and the cache priority can also be found in System.Web.Caching. The only difference is that Add is replaced with Insert&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114404751002391417?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114404751002391417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114404751002391417&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114404751002391417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114404751002391417'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/04/windows-form-cache.html' title='Windows form cache'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114366784046628141</id><published>2006-03-29T12:31:00.000-08:00</published><updated>2006-03-29T13:30:40.503-08:00</updated><title type='text'>SQL Session state</title><content type='html'>&lt;strong&gt;Enable session state&lt;/strong&gt;&lt;br /&gt;From the Visual Studio command prompt tool type&lt;br /&gt;Aspnet_regsql -S [SQL Server instance Name] -E -ssadd -sstype p&lt;br /&gt;&lt;br /&gt;-ssadd is to enable Sql Session State&lt;br /&gt;-E is using Windows Authentication.&lt;br /&gt;-sstype p Stores session state into persistent tables in the ASPState database instead of the tempdb database. Replace p with c to store session states in a custom database. The -d option is required then to add the name of the database.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;To add session state to your website&lt;/strong&gt;&lt;br /&gt;Add the following markup within the system.web tags (of the web.config file):&lt;br /&gt;&lt;br /&gt;sessionState mode="SQLServer" sqlConnectionString="&lt;br /&gt;Integrated Security=SSPI;data source=[SQL Server instance Name];" /&gt;&lt;br /&gt;&lt;br /&gt;For more information &lt;a href="http://msdn2.microsoft.com/en-us/library/ms178586(VS.80).aspx"&gt;Click here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114366784046628141?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114366784046628141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114366784046628141&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114366784046628141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114366784046628141'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/sql-session-state.html' title='SQL Session state'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114366423399737203</id><published>2006-03-29T11:57:00.000-08:00</published><updated>2006-03-29T12:30:52.573-08:00</updated><title type='text'>Dependency and Remove notification of ASP Cache</title><content type='html'>In ASP, you can add a cache dependency for a cache item. The cached item will then depend on an other item. If the other cached item changes, the cache of the depended item will be deleted&lt;br /&gt;&lt;br /&gt;string[] cachedObj = new string[1];&lt;br /&gt;cachedObj[0] = "Work";&lt;br /&gt;//Filename, Data&lt;br /&gt;CacheDependency dependency = new CacheDependency(null, cachedObj);&lt;br /&gt;//Key, value,  depens on&lt;br /&gt;Cache.Insert("DependentItem", "This item depends on OriginalItem", dependency);&lt;br /&gt;&lt;br /&gt;Cached items can also be inserted with timeouts&lt;br /&gt;&lt;br /&gt;Public Sub Insert ( key As String, value As Object, dependencies As CacheDependency, _    absoluteExpiration As DateTime,  slidingExpiration As TimeSpan, priority As CacheItemPriority, onRemoveCallback As CacheItemRemovedCallback )&lt;br /&gt;&lt;br /&gt;The absolute expiration is a datetime when the item will be removed. The slidingExpiration will remove the item if a given timespan period has passed.&lt;br /&gt;The &lt;A href="http://msdn2.microsoft.com/en-US/library/system.web.caching.cacheitempriority(VS.80).aspx"&gt;cache priority&lt;/a&gt; can be used to give the different cache items state priority. If the server needs memory, some cache will be deleted. Cached items with low priority will be deleted first. So don't store items to the cache that can not be retrieved anymore. Store them in other cache methods like: application state, session state, view state, cookie or hidden field.&lt;br /&gt;&lt;br /&gt;Also it's possible to add a postback function, if the cached item is deleted. The reason of deletion will also be reported.&lt;br /&gt;&lt;br /&gt; static bool itemRemoved = false;&lt;br /&gt;    static CacheItemRemovedReason reason;&lt;br /&gt;    CacheItemRemovedCallback onRemove = null;&lt;br /&gt;&lt;br /&gt;   &lt;strong&gt; public void RemovedCallback(String key, Object value, CacheItemRemovedReason reason)&lt;/strong&gt;{&lt;br /&gt;      itemRemoved = true;&lt;br /&gt;      reason = r;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void AddItemToCache(Object sender, EventArgs e) {&lt;br /&gt;        itemRemoved = false;&lt;br /&gt;&lt;br /&gt;        onRemove = new CacheItemRemovedCallback(this.RemovedCallback);&lt;br /&gt;&lt;br /&gt;        if (Cache["Obj"] == null)&lt;br /&gt;          Cache.Add("Obj", "Value of object", null, DateTime.Now.AddMinutes(20), TimeSpan.Zero, CacheItemPriority.High, onRemove);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void RemoveItemFromCache(Object sender, EventArgs e) {&lt;br /&gt;        if(Cache["Obj"] != null)&lt;br /&gt;          Cache.Remove("Obj");&lt;br /&gt;    }&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114366423399737203?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114366423399737203/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114366423399737203&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114366423399737203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114366423399737203'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/dependency-and-remove-notification-of.html' title='Dependency and Remove notification of ASP Cache'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114315242261813710</id><published>2006-03-23T11:15:00.000-08:00</published><updated>2006-03-26T23:03:18.786-08:00</updated><title type='text'>Libraries and Frameworks</title><content type='html'>Some really good libraries to make devloping more fun.&lt;br /&gt;&lt;br /&gt;&lt;a class="TitleLinkStyle" href="http://www.lhotka.net/WeBlog/CSLANET20ReleaseCodeAvailable.aspx"&gt;CSLA .NET 2.0 release code available&lt;/a&gt; (&lt;a href="http://www.lhotka.net/ArticleIndex.aspx?Area=CSLA%20.NET%2020"&gt;download it here&lt;/a&gt;)&lt;br /&gt;A framework using business objects. Closes the gap between E/R and OO. It's not exactly an O/R mapper. It works with entities in a object oriented aproach. Database support is provided. The framework makes applying of business rules easy. This is the 2.0 release, which is made for .NET framework 2.0&lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/library/?url=/library/en-us/dnpag2/html/EntLib2.asp"&gt;Enterprise library&lt;/a&gt;&lt;br /&gt;The Entrprise Library consists of several blocks.&lt;br /&gt;&lt;br /&gt;- Caching Application Block. Can be used for caching mechanism. Thread safe, limits the size of the cached item and also provide cache item(s) with a time out.&lt;br /&gt;- Cryptography Application Block. Same, but incorporate hashing and symmetric encryption in their applications.&lt;br /&gt;&lt;a href="http://davidhayden.com/blog/dave/archive/2006/01/08/2686.aspx"&gt;Data Access Application Block&lt;/a&gt;. Standarize data access using factory patterns, caching the (stored procedure) parameters.&lt;br /&gt;- Exception Handling Application Block. Throw and repack application errors to make it more user friendly.&lt;br /&gt;- Logging Application Block. Provides extra functionality to logging.&lt;br /&gt;- Security Application Block. Makes authorization and security easy.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/tomholl/archive/2006/03/22/558467.aspx"&gt;Enterprise library extensions&lt;/a&gt;&lt;br /&gt;This is the 2.0 release, which is made for framework 2.0&lt;br /&gt;Description of the extensions can be found &lt;a href="http://bloggingabout.net/blogs/olaf/archive/2006/01/30/10938.aspx"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Loads of other good blocks can be found at &lt;a href="http://msdn.microsoft.com/practices/compcat/default.aspx"&gt;the patterns and practices site from Microsoft.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sourceforge.net/projects/nhibernate"&gt;NHibernate O/R Mapper&lt;/a&gt;&lt;br /&gt;Library for persisting objects. Like other popular Jave open source projects ported from Java to .NET. It's one of the most popular open source O/R mapping tools of the moment. Puts mapping between data entities and objects into XML files. Retain performance due to smart features like lazy loading. Read more about it &lt;a href="http://www.codeproject.com/useritems/NHibernateBestPractices.asp"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sourceforge.net/projects/zedgraph"&gt;Zedgraph&lt;/a&gt;&lt;br /&gt;A library for graphics like bars, linegraphs etc.. As good as commercial products. Easy to use.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sourceforge.net/projects/ndoc"&gt;NDoc&lt;/a&gt;&lt;br /&gt;The open source library for generating help files (.chm) from XML comments in code.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sourceforge.net/projects/rainbowportal"&gt;Rainbow Portal&lt;/a&gt;&lt;br /&gt;A web portal projects with many modules to create a stunning site within minutes. Based on the IBuySpy portal.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/vb/net/GNWizard.asp"&gt;GN Wizard framework&lt;/a&gt;&lt;br /&gt;Small block to create wizards.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114315242261813710?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114315242261813710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114315242261813710&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114315242261813710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114315242261813710'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/libraries-and-frameworks.html' title='Libraries and Frameworks'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114305323561193995</id><published>2006-03-22T10:40:00.000-08:00</published><updated>2006-03-26T23:36:08.266-08:00</updated><title type='text'>Software factories or Model Driven Architecture?</title><content type='html'>Software factories (SF) or Model Driven Architecture (MDA)? Do we have to choose? And what is the difference between those?&lt;br /&gt;&lt;br /&gt;MDA will document a system with models and generates application code. Most MDA tools start with UML tooling. This is a platform independent way of modelling. The analyst/designer creates models like use cases, step plans, sequence diagrams, a global class diagram. An achitect can add a reference architecture to it. This can include platform specific models. Also the libraries and framework used can be added as models to the solution. Designers and developers can extend class diagrams, activity diagrams with the given information. Use  cases, sequence diagrams and class models are the models that suits most to be exported to real application code. The exported code can be platform specific. MDA uses an respository to store model information. All the system information needed including documents to build a system can be attached at the model. It's a living book of the system build. &lt;br /&gt;&lt;br /&gt;Software Factories model a small part of a system from a special kind of view. It's not possible to store all information of the system. Also SF is not used for a particular system. SF is like a pattern or template. Once developed, you can use it in all places where the pattern can be applied. It's also platform/environment specific. Although it can be applied to any thinkable environment. The pattern/template itself is described as a domain. The designer of Domain model is often an architect. A domein model can be for example a use case, class diagram, a template. A developer or designer can use the domein model to create a Domein specific language (DSL). I't can be described as applying a pattern to a system. This DSL can hold some information about the system. Class diagrams for example can be designed with DSL. With this DSL application code can be exported.&lt;br /&gt;&lt;br /&gt;Information from Microsoft&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/vstudio/teamsystem/workshop/sf/"&gt;Teamsystem Software Factories&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Some information about differences with MDA&lt;br /&gt;&lt;a href="http://blogs.msdn.com/jackgr/"&gt;Jack Greensfield's blog&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114305323561193995?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114305323561193995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114305323561193995&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114305323561193995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114305323561193995'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/software-factories-or-model-driven.html' title='Software factories or Model Driven Architecture?'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114284186453220659</id><published>2006-03-19T23:41:00.000-08:00</published><updated>2006-03-20T03:51:48.783-08:00</updated><title type='text'>ADO.NET Paging en SQL Server 2005 RowNumber</title><content type='html'>Oracle has a feature to make paging easy. Each result row gets a rownumber value. &lt;br /&gt;&lt;br /&gt;With SQL server 2005 this is also possible.&lt;br /&gt;&lt;br /&gt;The ROW_Number() will return the record row number&lt;br /&gt;The Over Function will do this by partitioning and/or order by clause on the table&lt;br /&gt;An inner select is needed to get numbered records.&lt;br /&gt;And after that a paging where clause concludes the SQL statement&lt;br /&gt;&lt;br /&gt;SELECT FirstName, LastName&lt;br /&gt;FROM&lt;br /&gt;   (SELECT ... &lt;br /&gt;         ROW_NUMBER() OVER(ORDER BY LastName) as RowNum&lt;br /&gt;    FROM Employees emp&lt;br /&gt;   ) &lt;br /&gt;WHERE RowNum BETWEEN @startRowIndex AND @startRowIndex + @maximumRows&lt;br /&gt;&lt;br /&gt;The strongly typed dataset and the SQL/XML datasources already supports paging by default. However if you define your own object datasource, you have to implement it yourself. Look at &lt; a href="http://www.nikhilk.net/DataSourceControlsSummary.aspx"&gt;Nikhil DataSource Controls"&gt; for a good example of creating a object datasource.&lt;br /&gt;&lt;br /&gt;Paging uses three methods. The select method must return a ILIST collection. And also an overload of the select method is needed with two parameter. The first parameter is the toppage recordnumber and the second parameter is the number of records shown on page. The third method is the "SelectCountMethod" which returns the record count.&lt;br /&gt;&lt;br /&gt;//Get data for a page&lt;br /&gt;//asp.net datasource, EnablePaging=true &lt;br /&gt;//SelectMethod=”GetItems”&lt;br /&gt;public IList&lt;Item&gt; GetItems(int startIndex, int maxRows)&lt;br /&gt;&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        //Get your data and return the list of items.&lt;br /&gt;        //Use the paging query described above&lt;br /&gt;        return myItems;&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;//Needed to get number of records for paging&lt;br /&gt;//ASP.NET datasource method SelectCountMethod&lt;br /&gt;   public int GetNumberOfItems()&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        return this.GetData().Count;&lt;br /&gt;&lt;br /&gt;    }&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114284186453220659?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114284186453220659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114284186453220659&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114284186453220659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114284186453220659'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/adonet-paging-en-sql-server-2005.html' title='ADO.NET Paging en SQL Server 2005 RowNumber'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114254751940322125</id><published>2006-03-16T13:23:00.000-08:00</published><updated>2006-03-19T23:41:42.910-08:00</updated><title type='text'>ADO.NET 2.0 / SQL Server 2005</title><content type='html'>In framework 1.1 we created our own factory mechanisme. We did this to be able tp connect with difference data providers. One day we would use Oracle and the next day we could use MySQL. I bet in most cases, this does not make sense. But the frameworks we work with will not exlude one. We do different projects. Each projectt has it's own requirements. So the database can be different by project. &lt;br /&gt;So with frameworks we like to be flixible. In 2.0 this is made easy using the DBProviderFactories. This provider may come from the connection string in the config file. You change the config file and on the same day we you will change from database provider. With such a provider, you will able to create a connection. Which information is also in the application's config file. And next create select a select command on the connection. This is just a SQL statement. With the select command you can create an adapter with the DbProviderFactory object. So you are able to retrieve and update students not knowing of any used database provider. So you don't need knowledge of a specific database. This starts rocking.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;private DataTable GetDataFromTable(string provider, string connectionString)&lt;br /&gt;{&lt;br /&gt;   DbProviderFactory dbFactory = DbProviderFactories.GetFactory(provider);&lt;br /&gt;   DbConnection connection = dbFactory.CreateConnection();&lt;br /&gt;   connection.ConnectionString = connectionString;&lt;br /&gt;   DbCommand command = connection.CreateCommand();&lt;br /&gt;            &lt;br /&gt;   // Select statement&lt;br /&gt;   command.CommandText = "SELECT Id, FirstName, LastName FROM Students";&lt;br /&gt;   DbDataAdapter adapter = dbFactory.CreateDataAdapter();&lt;br /&gt;   adapter.SelectCommand = command;&lt;br /&gt;   DataTable students = new DataTable();&lt;br /&gt;   // Fill the students table with data from the database&lt;br /&gt;   adapter.Fill(students);&lt;br /&gt;&lt;br /&gt;   return students;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;If the connection string is not in the web config. Yo can create one with the DbProviderFactory. With this builder, you can also manipulate the existing connection string. First set the connection string to the builder&lt;br /&gt; &lt;br /&gt;DbConnectionStringBuilder builder = dbFactory.CreateConnectionStringBuilder();&lt;br /&gt;builder.ConnectionString = connectionString&lt;br /&gt;&lt;br /&gt;And then add specific options. Be sure this time the conenction is SQLNCLI. Because the next line will set MARS on. &lt;br /&gt;builder.Add("MultipleActiveResultSets", "true");&lt;br /&gt;&lt;br /&gt;With MARS we will be able to open more connections at one time. But be carefull. More connections will cause performance loss. Never open more then 10 connections at the same time. And why should we want that?&lt;br /&gt;&lt;br /&gt;Did you know SQL server 2005 has adopter XML as datatype and has improved XML query support in SQL?&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnadonet/html/SqlXml_ADO.asp"&gt; XML Data Type Support in ADO.NET 2.0: Handling XML from SQL Server 2005&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Another beautyfull feature is the SQL Notification Services. With a call back functionality, it's possible to get noticed, if data in de database changes.&lt;br /&gt;There is a &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/querynotification.asp"&gt; good article on MSDN from Bob Beauchemin &lt;/a&gt;. He tells how notification services works.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114254751940322125?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114254751940322125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114254751940322125&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114254751940322125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114254751940322125'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/adonet-20-sql-server-2005.html' title='ADO.NET 2.0 / SQL Server 2005'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114244832788562366</id><published>2006-03-15T10:16:00.000-08:00</published><updated>2006-03-15T11:39:57.716-08:00</updated><title type='text'>BulkCopy (ADO.NET 2.0)</title><content type='html'>The BulkCopy command transfers data from a datasource to another. This can be directly from an execute reader to a database server. This can also be indirectly from an DataTable object to another.&lt;br /&gt;&lt;br /&gt;This is an example using the BulkCopy command. Connection strings can best be stored the application's config file. You can use a the command line tool "aspnet_regiis" to encrypt the connection string.&lt;br /&gt;e.g.&lt;br /&gt;aspnet_regiis -pe "connectionString" -app "/MyApplication". Connection strings will automatically be decrypted using the ConfigurationManager to read it. Other config sections can also easily be encrypted or decrypted. You can take a look at the blog of &lt;a href="http://davidhayden.com/blog/dave/archive/2005/11/17/2572.aspx"&gt;David Hayden&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The next thing is to read data from the database. This can be done by executing a query.&lt;br /&gt;&lt;br /&gt;string connectionString = ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString;&lt;br /&gt;SqlConnection myConnection = new SqlConnection(connectionString);&lt;br /&gt;SqlCommand myCommand = new SqlCommand("SELECT * FROM Products", myConnection);&lt;br /&gt;myConnection.Open();&lt;br /&gt;SqlDataReader dr = myCommand.ExecuteReader();&lt;br /&gt;&lt;br /&gt;For Bulkcopy, you need a new connection. Create a SqlBulkCopy instance with the second open connection. Set the destination table. Use columnmapping to match the table fields of the two tables.&lt;br /&gt;&lt;br /&gt;SqlConnection myNewConnection = new SqlConnection(connectionString);&lt;br /&gt;myNewConnection.Open();&lt;br /&gt;SqlBulkCopy bulk = new SqlBulkCopy(myNewConnection);&lt;br /&gt;bulk.DestinationTableName = "[Products]";&lt;br /&gt;bulk.ColumnMappings.Add("Name", "ProductName");&lt;br /&gt;bulk.ColumnMappings.Add("Price", "Price");&lt;br /&gt;bulk.ColumnMappings.Add("Amount", "Amount");&lt;br /&gt;&lt;br /&gt;Write the data of the reader to the second connection useing the SqlBukCopy object.&lt;br /&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;bulk.WriteToServer(dr);&lt;br /&gt;}&lt;br /&gt;catch (Exception ex)&lt;br /&gt;{&lt;br /&gt;Response.Write(ex.Message);&lt;br /&gt;}&lt;br /&gt;finally&lt;br /&gt;{&lt;br /&gt;myNewConnection.Close();&lt;br /&gt;dr.Close();&lt;br /&gt;myConnection.Close();&lt;br /&gt;bulk.Close();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Close the connections, even if something goes wrong. Close also the datareader en SQLBulkCopy instance.&lt;br /&gt;&lt;br /&gt;See a good article about indirect copying with BulkCopy from &lt;a href="http://www.dotnetjunkies.com/WebLog/joshuagough/archive/category/2692.aspx"&gt;Josh Gough&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114244832788562366?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114244832788562366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114244832788562366&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114244832788562366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114244832788562366'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/bulkcopy-adonet-20.html' title='BulkCopy (ADO.NET 2.0)'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114240889375891534</id><published>2006-03-14T23:18:00.000-08:00</published><updated>2006-03-15T11:46:13.710-08:00</updated><title type='text'>Toolstrip .Net 2.0</title><content type='html'>The &lt;strong&gt;ToolStrip&lt;/strong&gt; control is a new control in Windows Forms 2.0. It's a control for a menubar, toolbar or contect menu.&lt;br /&gt;&lt;br /&gt;The ToolStrip itself is a control where you can place different type of controls on. Most known is the Toolbar. This bar resides just below the menu control in an application. Look at the top of your screen and you will see. In the earlier days, this toolbar was fixed. Nowadays, its fully customizable. So you can dock the toolbar in one of the corners, but also place it where you want it. Same goes for the menu. The toolstrip is the a container for the toolbutton controls on the bar. Of course, any control can be placed.&lt;br /&gt;&lt;br /&gt;The &lt;strong&gt;ToolStripManager&lt;/strong&gt; can be custom rendered by setting the renderer of the ToolstripManager object to a derived class of the ToolStripSystemRenderer. Also be sure to enable visual styles. Get away gray buttons and let XP-style blink your forms.&lt;br /&gt;&lt;br /&gt;static void Main()&lt;br /&gt;{&lt;br /&gt;// Enable visual styles.&lt;br /&gt;Application.EnableVisualStyles();&lt;br /&gt;Application.SetCompatibleTextRenderingDefault(false);&lt;br /&gt;// Setup global rendrer.&lt;br /&gt;ToolStripManager.Renderer = new ToolstripRenderer();&lt;br /&gt;// Start application.&lt;br /&gt;Application.Run(new MainForm());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;A good implementation of this can be found at &lt;a href="http://www.chaliy.com/Sources/RebarRenderer/"&gt;RebarRendered&lt;/a&gt;&lt;br /&gt;Another example can be found at the &lt;a href="http://www.codeproject.com/useritems/CustomToolStripRenderer.asp"&gt;Code Project&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Basic toolstrip controls&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.toolstriplabel(VS.80).aspx"&gt;ToolStripLabel&lt;/a&gt;&lt;br /&gt;Used to display normal text, hyperlinks, and images.&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.toolstripbutton(VS.80).aspx"&gt;ToolStripButton&lt;/a&gt;&lt;br /&gt;Provides a typical pushbutton which supports both text and images.&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.toolstripcombobox(VS.80).aspx"&gt;ToolStripComboBox&lt;/a&gt;&lt;br /&gt;A ComboBox&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.toolstripseparator(VS.80).aspx"&gt;ToolStripSeparator&lt;/a&gt;&lt;br /&gt;A separator which visually separate groups of elements.&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.toolstripdropdownbutton(VS.80).aspx"&gt;ToolStripDropDownButton&lt;/a&gt;&lt;br /&gt;This control provides a button which, if clicked, displays a ToolStripDropDown control.&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.toolstriptextbox(VS.80).aspx"&gt;ToolStripTextBox&lt;/a&gt;&lt;br /&gt;A normal textbox which can be used to enter text.&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.toolstripmenuitem(VS.80).aspx"&gt;ToolStripMenuItem&lt;/a&gt;&lt;br /&gt;A special menu control built specifically for use with the MenuStrip and ContextMenuStrip controls.&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.toolstripprogressbar(VS.80).aspx"&gt;ToolStripProgressBar&lt;/a&gt;&lt;br /&gt;A specialized progress bar implementation for use within a StatusStrip control.&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.toolstripsplitbutton(VS.80).aspx"&gt;ToolStripSplitButton&lt;/a&gt;&lt;br /&gt;A combination of normal button and a DropDownButton. With has an arrow down buton for a dropdownlist og buttons&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.toolstripcontrolhost(VS.80).aspx"&gt;ToolStripControlHost&lt;/a&gt;&lt;br /&gt;A control that acts as a host for customized implementations or any other Windows Form controls.&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.toolstripcontainer(VS.80).aspx"&gt;ToolStripContainer&lt;/a&gt;&lt;br /&gt;A control that act a container for ToolStripControls&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;ToolStripControlHost&lt;/strong&gt; example&lt;br /&gt;The following examle with ad a calendar control to the toolstrip control host.&lt;br /&gt;MonthCalendar calend = new MonthCalendar();&lt;br /&gt;ToolStripControlHost host = new&lt;br /&gt;ToolStripControlHost(calend );&lt;br /&gt;calend.DateSelected += delegate(object sender,&lt;br /&gt;DateRangeEventArgs e)&lt;br /&gt;{ MessageBox.Show("You selected " +&lt;br /&gt;e.Start.ToShortDateString());&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;The control has to be added to the Toolstrip of course.&lt;br /&gt;&lt;br /&gt;Another way to do to use the &lt;strong&gt;ToolStripControlHost&lt;/strong&gt;, is to create &lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.toolstripcontrolhost(VS.80).aspx"&gt;derived class&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Some good example for working with the ToolStrip can be found at &lt;a href="http://www.devx.com/dotnet/Article/22001/0/page/3"&gt;Master Toolbars and Menus with the New ToolStrip Control&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Rafting &lt;/strong&gt;is the process of sliding a toolbar horizontally or vertically to place it in a particular location relative to other toolbars that share the same screen real estate. &lt;a href="http://www.devx.com/dotnet/Article/22001/0/page/4"&gt;Click here for an example of rafting&lt;/a&gt; Also be sure to take a look at the other pages of link.&lt;br /&gt;&lt;br /&gt;Lots of information can be found in a MS Word document about the ToolStrip. You can dowload it from &lt;a href="http://www.windowsforms.com/Samples/Go%20To%20Market/Tool%20Strips/ToolStrip%20GTM.doc"&gt;The Windows Form site -&gt; sampels -&gt; Market -&gt; Toolstrips&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114240889375891534?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114240889375891534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114240889375891534&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114240889375891534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114240889375891534'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/toolstrip-net-20.html' title='Toolstrip .Net 2.0'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114235074656796063</id><published>2006-03-14T07:32:00.000-08:00</published><updated>2006-03-15T11:48:14.893-08:00</updated><title type='text'>Exam 70-554, 70-553</title><content type='html'>I've looked on the internet and found out what kind of questions you can expect on these exams. I've post something about it earlier on this blog. I've already tried to pass 70-553. No results have been given to me about it yet.&lt;br /&gt;&lt;br /&gt;The exam 554 focuses on WSE 3.0, with special emphasis on SoapExtension, X509Certificate, Signing, Encryption and other security related items for web services and SOAP. Also remoting services using HttpChannel, TcpChannel and IpcChannel as web services and windows service hosted components.&lt;br /&gt;&lt;br /&gt;Numerous questions on application design, performance counters and identifying and correcting bottle necks.&lt;br /&gt;&lt;br /&gt;In exam 553, the &lt;a href="http://msdn2.microsoft.com/en-us/library/8xs8549b.aspx"&gt;backgroundworker&lt;/a&gt; is an important subject on the exam. So know sure how it works.&lt;br /&gt;On &lt;a href="http://www.mtelligent.com/"&gt;MTIntelligent&lt;/a&gt; you will find some resources for studying 553/554.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114235074656796063?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114235074656796063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114235074656796063&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114235074656796063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114235074656796063'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/exam-70-554-70-553.html' title='Exam 70-554, 70-553'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114219147741718696</id><published>2006-03-12T11:07:00.000-08:00</published><updated>2006-03-12T11:24:37.426-08:00</updated><title type='text'>SQL Server 2005 exceptions</title><content type='html'>It's new for sql server that there is no goto + raiseerror construction needed anymore. Now developers can use try... Catch. Reading the error from a query can be done from reading the global var @@error.  But now there is more information which can be read from inside the catch block.&lt;br /&gt;&lt;br /&gt;ERROR_LINE&lt;br /&gt;ERROR_MESSAGE&lt;br /&gt;ERROR_NUMBER&lt;br /&gt;ERROR_PROCEDURE&lt;br /&gt;ERROR_SEVERITY&lt;br /&gt;ERROR_STATE&lt;br /&gt;&lt;br /&gt;Severity level of the errors:&lt;br /&gt;0-10 information&lt;br /&gt;11-16 errors, which can be corrected. It can be functional or technical&lt;br /&gt;17-19 serious errors, administrators are needed to solve these problems. Errors are automaticlly logged in SQL Server log&lt;br /&gt;20-25 fatal errors, SQL server has to shut down. Errors are automaticlly logged in SQL Server log&lt;br /&gt;&lt;br /&gt;Errors 0-16 can be read from the InfoMessage property of the Command object.&lt;br /&gt;Custom errors can be crated in a range from 50.001.&lt;br /&gt;&lt;br /&gt;Exceptions which have to be transported between layers can best be send in XML format. Only in a binary pipe transport, the exception object itselves can be used.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114219147741718696?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114219147741718696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114219147741718696&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114219147741718696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114219147741718696'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/sql-server-2005-exceptions.html' title='SQL Server 2005 exceptions'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114211527417531294</id><published>2006-03-11T11:56:00.000-08:00</published><updated>2006-03-15T11:55:22.290-08:00</updated><title type='text'>Data Access strategies</title><content type='html'>Drag and Drop facilities, SmartTags and lots of configurations were made to make data access easy. On the other hand, although this productive manner is beautyfully, we software developers hardly have used to do it this way. Why don't we? Because of the frameworks and Middle tiers. We must cope with business tiers, process layers, task controllers and authorization en authentication control. What does Microsoft say about it? Use the Microsoft Enterprise Block. And later on Linq, with SQLMetal. &lt;br /&gt;&lt;br /&gt;Linq is a query language which hides database dialects. And brings querying of different datasources under one roof. SQL Metal will map business entities and database objects. So we don't have to write that time consuming Data Access Layrer Anymore. Unfortunately, it's not out. So we have to wait for it.&lt;br /&gt;&lt;br /&gt;There are a good things about using the Enterpise Data Access Block from the Enterpsie Library. The Enterprise Library also has a good caching mechanism library. Other blocks like security, logging configuration are of lesser use. One of the most used blocks is still Data access application block. This is recommendated and worthy updated in version 2.0. Good work guys. See also the weblog of &lt;a href="http://www.agileprogrammer.com/oneagilecoder/archive/2006/01/03/10564.aspx"&gt;Brian Button&lt;/a&gt; about it.&lt;br /&gt;&lt;br /&gt;And what is the best data access then?&lt;br /&gt;- Map database tables to classes and field to properties. Use generation tools to manage this.&lt;br /&gt;- cache referential data such a country at the server (as the client)&lt;br /&gt;- Use connections as short as possible and use connection pooling Close connections soon as possible&lt;br /&gt;- Only get the data you want. Don't retrieve all columns and rows of a table.&lt;br /&gt;- Use things as timestamp fields in tables to support multi-user concurrency. Who was the first and who missed goal. And what should happen then?&lt;br /&gt;- Use the best provider. The provider should be flexible. In one project more then one data source providers should be choosen.&lt;br /&gt;- Also query provider independent the database. See Linq as a solution.&lt;br /&gt;- Make XML persist and retrieval possible. Due the SOA architecture, webservices are used in many projects. Datasets publishes to much traffic. Also with HTTP GZIP compression. Make sure, your application using a webservice is able to send data in an XML format to the front end and back.&lt;br /&gt;&lt;br /&gt;Further reading&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/msdnmag/issues/05/05/DataPoints/default.aspx"&gt;Datapoints 2005-05 Data Access Strategies Using ADO.NET and SQL&lt;/a&gt;&lt;br /&gt;&lt;a href="http://authors.aspalliance.com/aspxtreme/webforms/dataaccessstrategy.aspx"&gt;Web data access strategy recommendations&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114211527417531294?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114211527417531294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114211527417531294&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114211527417531294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114211527417531294'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/data-access-strategies.html' title='Data Access strategies'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114209411186474023</id><published>2006-03-11T08:07:00.000-08:00</published><updated>2006-03-11T08:22:55.486-08:00</updated><title type='text'>SQLNCLI (SQL Native Client)</title><content type='html'>SQl server uses a new database provider model. This provider succeeds OLEDB. OLEDB was used for SQL Server databases. Now even it's possible to access MS Access databases that way. ODBC is only for backward compatability. The new SQLNCLI provider has the following new features&lt;br /&gt;- Support for the new SLQ 2005 large datatypes (Max String, with no limited length)&lt;br /&gt;- XML Datatype (Not just a handle, but a real type)&lt;br /&gt;- Custom Datatypes (UDT)&lt;br /&gt;-The new snapshot isolation level. This level does not lock dirty reads. It uses optimistic (locking). It's the best of both worlds. Enabled to read all actual committed data, skipping locks, but reading the data (dirty reads), and persisting data if the data is not locked.&lt;br /&gt;- Supprot for multiple active recordsets. It was already possible to get multiple recordsets. In Ado.Net, with movenext, the next result could be read. But now, it's possible to have multiple connections open. So each recordset (multiple retrieval) can have it's own connection.&lt;br /&gt;- Password can be changed at the client, without the need of the administrator. &lt;br /&gt;- Support for asynchoon operations. Lots of complex database actions take a time. Now SQL server can create threads to do jobs on its own. &lt;br /&gt;- It supports SQLXML 4.0. &lt;br /&gt;&lt;br /&gt;The new connection string (just another provider)&lt;br /&gt;"Provider=SQLNCLI;Server=(local);Database=Northwind;IntegratedSecurity=SSPI;"&lt;br /&gt;&lt;br /&gt;For DSN connections (who uses them still?)&lt;br /&gt;"Driver={SQL Native Client}; Server=(local); Database=Northwind;&lt;br /&gt;Trusted_Connection=yes;"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114209411186474023?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114209411186474023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114209411186474023&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114209411186474023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114209411186474023'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/sqlncli-sql-native-client.html' title='SQLNCLI (SQL Native Client)'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114189919646623320</id><published>2006-03-09T01:25:00.000-08:00</published><updated>2006-03-09T02:13:16.490-08:00</updated><title type='text'>ClickOnce</title><content type='html'>A ClickOnce deployment is controlled through the use of two XML manifest files: a deployment manifest and an application manifest.&lt;br /&gt;&lt;br /&gt;Deployment Manifest file&lt;br /&gt;The deployment manifest file describes the deployment model:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the current version&lt;/li&gt;&lt;li&gt;update behavior&lt;/li&gt;&lt;li&gt;publisher identity along with digital signature. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Update Refresh time and update application time&lt;br /&gt;&lt;br /&gt;subscription&lt;br /&gt;update&lt;br /&gt;expiration unit="hours" maximumage="6"&lt;br /&gt;beforeApplicationStartup /&lt;br /&gt;/update&lt;br /&gt;subscription&lt;br /&gt;&lt;br /&gt;If the bandwithspeed is slow, it's advisable to set de update after the application starts. The new version will start next time&lt;br /&gt;&lt;br /&gt;Configuration can be done with the application update dialog box&lt;br /&gt;To access this dialog box, select a project node in Solution Explorer, then on the Project menu, click Properties. When the Project Designer appears, click the Publish tab. On the Publish page, click the Updates button.&lt;br /&gt;(Source: &lt;a href="http://msdn2.microsoft.com/en-us/library/s22azw1e(VS.80).aspx"&gt;http://msdn2.microsoft.com/en-us/library/s22azw1e(VS.80).aspx&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;The deployment manifest is intended to be authored by administrators who handle deployment.&lt;br /&gt;Application manifest file&lt;br /&gt;The application manifest - a .exe.manifest file - describes&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the application assemblies&lt;/li&gt;&lt;li&gt;dependent libraries &lt;/li&gt;&lt;li&gt;lists permissions required by the application. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;This file is intended to be authored by the application developer. In order to launch a ClickOnce application, a user clicks on its deployment manifest file.&lt;br /&gt;&lt;br /&gt;Updating the application can be done automatically or by api&lt;br /&gt;private void OnUpdateApplication(object sender, EventArgs e)&lt;br /&gt;{ ApplicationDeployment deployment = ApplicationDeployment.CurrentDeployment; if (deployment.CheckForUpdate()) { deployment.Update(); MessageBox.Show("Update downloaded, application" + "will now restart."); Application.Restart(); } else { MessageBox.Show("No updates available"); }}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Deploying com components is possible. But the com component have to be isolated or a bootstrapper is needed (Source &lt;a href="http://msdn2.microsoft.com/en-us/library/ms165432(VS.80).aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms165432(VS.80).aspx&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Choosing between windows installer or using clickonce:&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/142dbbz4(VS.80).aspx"&gt;http://msdn2.microsoft.com/en-us/library/142dbbz4(VS.80).aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Deploying an clickonce application manually can be done by user not familiair with visual sutdio. There is a command-line tool called mage and a windows forms UI tool (same functionality) MageGUI for this.&lt;br /&gt;See &lt;a href="http://msdn2.microsoft.com/en-us/library/xc3tc5xx(VS.80).aspx"&gt;http://msdn2.microsoft.com/en-us/library/xc3tc5xx(VS.80).aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To decrease the download time. Assemblies can be downloaded on demand. This can be done by the designer or by API. See &lt;a href="http://msdn2.microsoft.com/en-us/library/ak58kz04(VS.80).aspx"&gt;http://msdn2.microsoft.com/en-us/library/ak58kz04(VS.80).aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Other sources&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/142dbbz4(VS.80).aspx"&gt;MSDN Overview&lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/ClickOnce"&gt;Wikipedia definition&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.theserverside.net/articles/showarticle.tss?id=AutomatedSmartClient"&gt;Automated Smart Client &amp;amp; Update&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.devtips.net/article.aspx?id=121" target="_blank"&gt;DevTips -Applicaties distribueren met ClickOnce&lt;/a&gt; (Dutch)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114189919646623320?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114189919646623320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114189919646623320&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114189919646623320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114189919646623320'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/clickonce.html' title='ClickOnce'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114181567590918555</id><published>2006-03-08T02:27:00.001-08:00</published><updated>2006-03-08T03:02:02.373-08:00</updated><title type='text'>Backgroundworker threads</title><content type='html'>&lt;p&gt;The BackgroundWorker class is a component in Windows Forms applications that can be used for task which take some time. Task will be run in a dedicated thread (asynchr). You can drag de background wordker from the compenent tab in the toolbox on to the form. &lt;/p&gt;&lt;p&gt;In a triggered method, create the events if the thread has to be created. Implement 3 events. The work event, the completed event and de progress changed event. This does not trigger the thread, but only implements the functionality&lt;/p&gt;&lt;p&gt;private void InitializeBackgoundWorker()&lt;br /&gt;{&lt;br /&gt;backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);&lt;br /&gt;backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler( backgroundWorker1_RunWorkerCompleted);&lt;br /&gt;backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler( backgroundWorker1_ProgressChanged);&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;Example implementation DoWork event:&lt;/p&gt;&lt;p&gt;private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)&lt;br /&gt;{&lt;br /&gt;BackgroundWorker worker = sender as BackgroundWorker;&lt;br /&gt;e.Result = DoLongWork((int)e.Argument, worker, e);&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;The sender is de background worker. The eventargs contain the option for cancelling the operation. The worker object tells abut the status. The user could have choosen to cancel the operation. If the consuming time function is executing. The worker status can be questionned along the way. A user could have choosen the cancel the operation.&lt;/p&gt;&lt;p&gt;if (worker.CancellationPending) { e.Cancel = true; }&lt;br /&gt;&lt;/p&gt;&lt;p&gt;With the function backgroundWorker1.CancelAsync(); the thread can be cancelled.With the function backgroundWorker1.RunWorkerAsync(numberToCompute); the thread can be started.&lt;br /&gt;&lt;br /&gt;After completing or cancelling the thread the Completed event will be triggered&lt;/p&gt;&lt;p&gt;private void backgroundWorker1_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e) { }&lt;/p&gt;&lt;p&gt;The eventargs contains the result.&lt;/p&gt;&lt;p&gt;e has attribute error. The e.Error can be set in the DoWork event&lt;br /&gt;e has attribute cancelled. The e.Cancelled can be set in the DoWork event&lt;br /&gt;e has attribute result. Also can be set in the DoWork event.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;In the DoWork event the progress can be reported. Call worker.ReportProgress(percentComplete);&lt;/p&gt;&lt;p&gt;In the event handler of ProgessChanged read the value:&lt;/p&gt;&lt;p&gt;private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)&lt;br /&gt;{&lt;br /&gt;textBoxCompleted.Text = e.ProgressPercentage.ToString() + "% completed";&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114181567590918555?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114181567590918555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114181567590918555&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114181567590918555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114181567590918555'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/backgroundworker-threads_08.html' title='Backgroundworker threads'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114181260841870994</id><published>2006-03-08T02:05:00.000-08:00</published><updated>2006-03-08T02:10:08.430-08:00</updated><title type='text'>Parameterized threads</title><content type='html'>This is a new feature of 2.0. You can start a thead calling a function with a parameter. It may come in handy with doing transactions in different threads.&lt;br /&gt;&lt;br /&gt;Thread myThread;&lt;br /&gt;myThread =&lt;br /&gt;new System.Threading.Thread(new ParameterizedThreadStart(ThreadEntryPoint));&lt;br /&gt;Transaction currentTransactionClone = Transaction.Current.Clone();&lt;br /&gt;myThread.Start(currentTransactionClone); //Giving parameter&lt;br /&gt;&lt;br /&gt;//Thread function with parameter&lt;br /&gt;private static void ThreadEntryPoint(object transactionInstance)&lt;br /&gt;{&lt;br /&gt; Transaction currentTransactionClone = (Transaction)transactionInstance;&lt;br /&gt; using (SqlConnection connection2 = new SqlConnection(connectionString2))&lt;br /&gt;  {&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;     connection2.Open();&lt;br /&gt;     connection2.EnlistTransaction(currentTransactionClone);&lt;br /&gt;    }&lt;br /&gt;   catch (Exception ex)&lt;br /&gt;    {&lt;br /&gt;     currentTransactionClone.Rollback();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114181260841870994?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114181260841870994/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114181260841870994&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114181260841870994'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114181260841870994'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/parameterized-threads.html' title='Parameterized threads'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114180902548679509</id><published>2006-03-08T00:36:00.000-08:00</published><updated>2006-03-15T06:59:55.670-08:00</updated><title type='text'>Dev Days 2006</title><content type='html'>I have been to the Dutch Developer Days 2006. It's a two day event. I was invited for one day only. Pity for me. Lot's of my collegues were invited too. My company is main sponsor of the event. I've seen a lot of cool stuff, that will be released this year. Window Visa is hot. XAML is very hot. The Microsoft people managed to use every apsect of the graphic card to make Windows stunning. For making Hollywoord films, no Apple Macintosh is required anymore to show stunning stuff on a screen. 3D visualisations, glass effects and the cool desktop gadgets makes the upgrade wordthy. Scott Guthrie talked about Atlas. A very cool feature for refreshing the web page partially. There was also a session about DSL. But the presentation was not well done. I wish there were more sessions about this cool topic.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2006/03/12/440068.aspx"&gt;Atlas - Scott Guthrie&lt;/a&gt;&lt;br /&gt;&lt;a href="http://codebetter.com/blogs/peter.van.ooijen/archive/2006/03/12/140744.aspx"&gt;Photo's DevDays 2006&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Workflow Foundation&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/01/WindowsWorkflowFoundation/"&gt;MSDN Magazine 06-01 Windows Workflow Foundation&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/03/CuttingEdge/default.aspx"&gt;Cutting Edge - Dino Esposito 06-03&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/04/CuttingEdge/"&gt;Cutting Edge - Dino Esposito 06-04&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/windowsvista/building/workflow/default.aspx?pull=/library/en-us/dnlong/html/wfgetstart.asp"&gt;Get Started With Workflow Foundation&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/windowsvista/default.aspx?pull=/library/en-us/dnlong/html/intWF_FndRlsEng.asp"&gt;Another article on Workflow Foundation&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114180902548679509?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114180902548679509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114180902548679509&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114180902548679509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114180902548679509'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/dev-days-2006.html' title='Dev Days 2006'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114165308921126688</id><published>2006-03-06T05:35:00.000-08:00</published><updated>2006-03-08T00:36:06.286-08:00</updated><title type='text'>Exam 70-553/71-553</title><content type='html'>I've done exam 70-553 this monday. It's an upgrade exam for MCSD (Microsoft Certified Solution Developer) to become MCPD (Microsoft Certified enterprise application developer).&lt;br /&gt;&lt;br /&gt;The exam took 230 minutes (180 minutes for questions) and exists of 3 smaller exams of 60 minutes each. One exam with Windows Form questions, one with Web application questions and one with C#/VB.NET Framework 2.0 questions. You can choose to do this exam in C# or VB.NET in the beginning of the exam. &lt;br /&gt;&lt;br /&gt;In the winform exam there were questions about the following topics:&lt;br /&gt;- Toolstrip&lt;br /&gt;- Flatstyle button, VisualBackStyle not working, what to do.&lt;br /&gt;- Context menu (popup calendar) for a textbox with is meant for dates. The control is not a datetimepicker&lt;br /&gt;- ClickOnce, which situation to use and when windows installer?&lt;br /&gt;- ClickOnce, not in GAC, no shared users, No registry, No startup, can create shortcut etc..&lt;br /&gt;- ClickOnce other questions with partial download assemblies. It's all about the application and manifest file.&lt;br /&gt;- DatagridView, column name change methods/paths&lt;br /&gt;- ADO.Net, datagridview master/details, creating relation between them&lt;br /&gt;&lt;br /&gt;In the webform questions about:&lt;br /&gt;- Mobile filter (device supports color, black white logo)&lt;br /&gt;- Webparts&lt;br /&gt;- Masterpage (default content place holder)&lt;br /&gt;- Connections between webparts&lt;br /&gt;- Webpart control that set location and size webpart&lt;br /&gt;- Sitemap, treeview control&lt;br /&gt;- deployment method without sources&lt;br /&gt;- deployment method without source, with ftp&lt;br /&gt;- deployment method with source&lt;br /&gt;&lt;br /&gt;Framework&lt;br /&gt;- Security (windows principal, genric identity)&lt;br /&gt;- Generic collections (easy ones)&lt;br /&gt;- Cryptography&lt;br /&gt;- XML checking, validating xsd&lt;br /&gt;- XML editing, adding book node, after another&lt;br /&gt;- Threads (long processing methods, several)&lt;br /&gt;- Transactions (transactionscope)&lt;br /&gt;- Debugging and tracing&lt;br /&gt;&lt;br /&gt;and lots more. Total of questions 90. Result of the exam taken will be given if beta exam is released. And score report will arrive three months after that or more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114165308921126688?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114165308921126688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114165308921126688&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114165308921126688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114165308921126688'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/03/exam-70-55371-553.html' title='Exam 70-553/71-553'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114063268583777662</id><published>2006-02-22T10:14:00.000-08:00</published><updated>2006-02-22T10:34:40.070-08:00</updated><title type='text'>Mobile devices</title><content type='html'>I haven't developed mobile applications yet. I must be fun to write them, though. With websites you can make a difference between mobile and not mobile decice applications. Because mobile devices have small screen display it's advisable to use smaller webpages and images then you would for other devices.&lt;br /&gt;&lt;br /&gt;devicefilters&gt;&lt;br /&gt;filter argument="true" compare="IsMobileDevice" name="MobileDeviceChoice"&lt;br /&gt;/devicefilters&gt;&lt;br /&gt;&lt;br /&gt;In de web config you can add a section to filter mobile devices. The compare attribute is important.&lt;br /&gt;&lt;br /&gt;In the webpage you can filter now between mobile and not mobile devices by adding the tag Choice and attribute Filter:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;?xml:namespace prefix = mobile /&gt;&lt;mobile:form id="_mobileForm " runat="server"&gt;&lt;br /&gt;mobile:devicespecific id="_deviceSpecific" runat="server"&gt;&lt;br /&gt;choice filter="MobileDeviceChoice"&gt;&lt;br /&gt;headertemplate&gt;&lt;br /&gt;img src="images/SmallCompanyLogo.jpg" /&gt;&lt;br /&gt;/headertemplate&gt;&lt;/choice&gt;&lt;br /&gt;choice&gt;&lt;br /&gt;headertemplate&gt;&lt;br /&gt;img src="images/CompanyLogo.jpg" /&gt;&lt;br /&gt;/headertemplate&gt;&lt;br /&gt;/choice&gt;&lt;br /&gt;/mobile:devicespecific&gt;&lt;br /&gt;/mobile:form&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You should not add two DeviceSpecific controls to the form. Only one DeviceSpecific control is supported per container control.&lt;br /&gt;&lt;br /&gt;You cannot add a HeaderTemplate element as a child of the DeviceSpecific element. HeaderTemplate elements must be added as children of Choice elements. The HeaderTemplate element allows you to specify a header template for a specific device. This means that you can display different headers and footers per device, while displaying the same inner content for all devices.&lt;br /&gt;&lt;br /&gt;You should not add two HeaderTemplate elements to the same Choice element. Only a single HeaderTemplate element is supported for each Choice element.&lt;br /&gt;&lt;br /&gt;&lt;/mobile:form&gt;&lt;?xml:namespace prefix = mobile /&gt;&lt;mobile:form id="_mobileForm " runat="server"&gt;&lt;/mobile:form&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114063268583777662?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114063268583777662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114063268583777662&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114063268583777662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114063268583777662'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/02/mobile-devices.html' title='Mobile devices'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114051450030288066</id><published>2006-02-20T23:55:00.000-08:00</published><updated>2006-02-21T01:35:00.330-08:00</updated><title type='text'>Links for LINQ</title><content type='html'>&lt;span style="font-size:78%;"&gt;"&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/netframework/future/linq/"&gt;&lt;span style="font-size:85%;"&gt;MSDN .NET Framework Developer Center: The LINQ Project&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;"&gt; Start site Linq&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:78%;"&gt;"&lt;/span&gt;&lt;a href="http://www.code-magazine.com/Article.aspx?quickid=050133"&gt;Linq Up&lt;/a&gt;&lt;span style="font-size:78%;"&gt;"&lt;/span&gt; Code Magazine &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;"&lt;/span&gt;&lt;a href="http://www.microsoft.com/belux/nl/msdn/community/columns/himschoot/linq.mspx"&gt;C# 3.0 and LINQ&lt;/a&gt;&lt;span style="font-size:78%;"&gt;"&lt;/span&gt; MSDN&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;div align="left"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/netframework/default.aspx?pull=/library/en-us/dndotnet/html/linqcomparisons.asp"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;Comparing LINQ and Its Contemporaries&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;/span&gt;&lt;a href="http://www.ftponline.com/vsm/2005_12/magazine/features/rjennings_orcas/"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;Streamline Mapping With Orcas and LINQ&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;br /&gt;"&lt;/span&gt;&lt;a href="http://www.ftponline.com/channels/net/reports/pdc/2005/jennings-linq/default_pf.aspx"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;Cure Data Type 'Impedance Mismatch' With LINQ&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;" &lt;br /&gt;"&lt;/span&gt;&lt;a href="http://oakleafblog.blogspot.com/2005/09/language-integrated-query-linq-project.html"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;The Language Integrated Query (LINQ) Project&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;" &lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;/span&gt;&lt;a href="http://oakleafblog.blogspot.com/2005/09/erik-meijer-on-linq-as-6gl-language.html"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;Erik Meijer on LINQ as a 6GL Language Feature&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;" &lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;/span&gt;&lt;a href="http://oakleafblog.blogspot.com/2005/09/linq-interview-with-anders-hejlsberg.html"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;LINQ Interview with Anders Hejlsberg and Paul Vick&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;br /&gt;"&lt;/span&gt;&lt;a href="http://oakleafblog.blogspot.com/2005/09/jon-udell-microsoft-driving-toward-net.html"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;Jon Udell: Microsoft driving toward .Net unity&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;br /&gt;"&lt;/span&gt;&lt;a href="http://oakleafblog.blogspot.com/2005/09/xlinq-presentation-at-xml-2005.html"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;XLinq Presentation at the XML 2005 Conference&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;br /&gt;"&lt;/span&gt;&lt;a href="http://oakleafblog.blogspot.com/2005/09/comparing-c-30-and-vb-90-linq-syntax.html"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;Comparing C# 3.0 and VB 9.0 LINQ Syntax&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;br /&gt;"&lt;/span&gt;&lt;a href="http://oakleafblog.blogspot.com/2005/09/more-on-object-xml-and-object.html"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;More on Object-XML and Object-Relational Impedance Mismatch&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;br /&gt;"&lt;/span&gt;&lt;a href="http://oakleafblog.blogspot.com/2005/09/jon-udell-linq-101.html"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;Jon Udell: LINQ 101&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;" &lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;/span&gt;&lt;a href="http://oakleafblog.blogspot.com/2005/10/compose-xml-content-with-xlinq.html"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;Compose XML Content with XLinq Expressions and VB 9.0 XML Literals&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;&lt;br /&gt;"&lt;/span&gt;&lt;a href="http://oakleafblog.blogspot.com/2005/10/more-on-visual-basic-90-and-linq.html"&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;More on Visual Basic 9.0 and LINQ versus SQL&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;"&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114051450030288066?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114051450030288066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114051450030288066&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114051450030288066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114051450030288066'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/02/links-for-linq.html' title='Links for LINQ'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114047175896327220</id><published>2006-02-20T13:37:00.000-08:00</published><updated>2006-02-21T02:22:04.433-08:00</updated><title type='text'>New features in C# 2.0 part 1</title><content type='html'>Nullable types: Makes a value type accept null values&lt;br /&gt;int? count=null;&lt;br /&gt;&lt;br /&gt;Null value replacement: replaces the null value of a ? value type with an other value, if so&lt;br /&gt;int ? count=null&lt;br /&gt;int x = count ?? 0&lt;br /&gt;&lt;br /&gt;Custom Exception Data: Add extra data to exceptions&lt;br /&gt;Data is of type generic.collection.dictionary(string, string)&lt;br /&gt;Exception ex&lt;br /&gt;ex.Data.Add("User Comment","Stupid error");&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114047175896327220?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114047175896327220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114047175896327220&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114047175896327220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114047175896327220'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/02/new-features-in-c-20-part-1.html' title='New features in C# 2.0 part 1'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-114046337891581708</id><published>2006-02-20T11:15:00.000-08:00</published><updated>2006-02-20T11:26:26.266-08:00</updated><title type='text'>Study Material</title><content type='html'>There is not much material for the new beta exams avaiable. Does anyone have tips? I like to prepare for 70-553. I noticed that quickonce, mobile development and deployment is very important. Has anyone made or found study material to share?.&lt;br /&gt;&lt;br /&gt;Skils to be measured:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/learning/exams/70-551.asp"&gt;70-551 - UPGRADE: MCAD Skills to MCPD Web Developer by Using the Microsoft .NET Framework&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/learning/exams/70-552.asp"&gt;70-552 - UPGRADE: MCAD Skills to MCPD Windows Developer by Using the Microsoft .NET Framework&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/learning/exams/70-553.asp"&gt;70-553 - UPGRADE: MCSD Microsoft .NET Skills to MCPD Enterprise Application Developer by Using the Microsoft .NET Framework: Part 1&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/learning/exams/70-554.asp"&gt;70-554 - UPGRADE: MCSD Microsoft .NET Skills to MCPD Enterprise Application Developer by Using the Microsoft .NET Framework: Part 2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Some information can be found at &lt;a href="http://en.wikibooks.org/wiki/Microsoft_Certified_Professional_Developer"&gt;http://en.wikibooks.org/wiki/Microsoft_Certified_Professional_Developer&lt;/a&gt;&lt;br /&gt;(links to MSDN on-line)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-114046337891581708?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/114046337891581708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=114046337891581708&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114046337891581708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/114046337891581708'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2006/02/study-material.html' title='Study Material'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-112004266339582477</id><published>2005-06-29T03:50:00.000-07:00</published><updated>2005-06-29T03:59:23.343-07:00</updated><title type='text'>Performance counter</title><content type='html'>This performance qounter is more aqurate then the timer of microsoft. Which is in milliseconds. This timer can be used to measure performance issue in code. Making it a struct makes it easy to use it. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Encapsulates the high performance query counter &lt;br /&gt;/// unmanaged Windows API in a small structure (not &lt;br /&gt;/// an object which would require garbage collection,&lt;br /&gt;/// heap, etc...)&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;/// &lt;example&gt;&lt;br /&gt;/// string s = "";&lt;br /&gt;/// HighPerformanceTimer timer = new HighPerformanceTimer();&lt;br /&gt;/// timer.Start();&lt;br /&gt;/// // do something here you want to measure ...&lt;br /&gt;/// for(int i = 0; i &lt; 1000; i++) {&lt;br /&gt;///   s += string.Format("=.=.=.= {0}", i);&lt;br /&gt;/// }&lt;br /&gt;/// timer.Stop();&lt;br /&gt;/// Console.WriteLine(&lt;br /&gt;///   string.Format("Result {0:0.##}", &lt;br /&gt;///         timer.TotalElapsed));&lt;br /&gt;/// &lt;/example&gt;&lt;br /&gt;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;using System.Threading;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public struct HighPerformanceTimer&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;[System.Security.SuppressUnmanagedCodeSecurityAttribute]&lt;br /&gt;private sealed static class QueryPerformanceTimer&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;[ DllImport("Kernel32.dll") ]&lt;br /&gt;public static extern bool QueryPerformanceCounter(out long lpPerformanceCount);&lt;br /&gt;&lt;br /&gt;[ DllImport("Kernel32.dll") ]&lt;br /&gt;public static extern bool QueryPerformanceFrequency(out long lpFrequency);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private long _frequency;&lt;br /&gt;private long _startTime;&lt;br /&gt;private long _endTime;&lt;br /&gt;&lt;br /&gt;public long Frequency {&lt;br /&gt;  get {&lt;br /&gt;    if (_frequency == 0) {&lt;br /&gt;      QueryPerformanceTimer.QueryPerformanceFrequency(out _frequency);&lt;br /&gt;    }&lt;br /&gt;    return _frequency;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public long Start() {&lt;br /&gt;  _endTime = 0;&lt;br /&gt;  // lets do the waiting threads there work&lt;br /&gt;  Thread.Sleep(0);&lt;br /&gt;  QueryPerformanceTimer.QueryPerformanceCounter(out _startTime);&lt;br /&gt;  return _startTime;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public long Stop() {&lt;br /&gt;  QueryPerformanceTimer.QueryPerformanceCounter(out _endTime);&lt;br /&gt;  return _endTime;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public double GetCurrentElapsed() {&lt;br /&gt;  long currentTime = 0;&lt;br /&gt;  QueryPerformanceTimer.QueryPerformanceCounter(out currentTime);&lt;br /&gt;&lt;br /&gt;  if (_startTime !=0) { &lt;br /&gt;    return ToElapsed(_startTime, currentTime);&lt;br /&gt;  }&lt;br /&gt;  return -1D;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public double TotalElapsed {&lt;br /&gt;  get { &lt;br /&gt;    if (_endTime == 0) {&lt;br /&gt;      return GetCurrentElapsed();&lt;br /&gt;    }&lt;br /&gt;    return ToElapsed(_startTime, _endTime);&lt;br /&gt;  } &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private double ToElapsed(long startTime,&lt;br /&gt;                         long endTime) {&lt;br /&gt;  double total = (double)(endTime - startTime) * 1000 &lt;br /&gt;      / (double) Frequency;&lt;br /&gt;  return total;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-112004266339582477?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/112004266339582477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=112004266339582477&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/112004266339582477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/112004266339582477'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2005/06/performance-counter.html' title='Performance counter'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-111814752323849229</id><published>2005-06-07T05:27:00.000-07:00</published><updated>2005-06-07T05:32:03.240-07:00</updated><title type='text'>static constructor</title><content type='html'>Bestaat dit? Ja volgens de C# specificatie wel.&lt;br /&gt;&lt;br /&gt;class x&lt;br /&gt;{&lt;br /&gt; int var;&lt;br /&gt; static x()&lt;br /&gt;{&lt;br /&gt; if (System.DateTime.Now.Date.ToString(u)=='2004-06-06)')&lt;br /&gt;   Console.WriteLine('Happens');&lt;br /&gt; else&lt;br /&gt;  Console.WriteLine('Shit Happens');&lt;br /&gt;}&lt;br /&gt; x()&lt;br /&gt;{&lt;br /&gt; var=1;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Static constructor betekent niet het intialiseren van variabelen maar van de class en wordt voor de eigenlijke constructor aangeroepen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-111814752323849229?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/111814752323849229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=111814752323849229&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/111814752323849229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/111814752323849229'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2005/06/static-constructor.html' title='static constructor'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-111814606881598465</id><published>2005-06-07T04:24:00.000-07:00</published><updated>2005-06-07T05:27:32.480-07:00</updated><title type='text'>Unit test</title><content type='html'>In mijn huidige project gaan we nUnit gebruiken. Ik had hier nog niets mee gedaan, wel gelezen. De laatste versie is 2.2 en is op www.nunit.org te downloaden. De tool is handig, maar de website biedt summiere informatie. Vandaar dat veel mensen het toc nog laten voor wat het is. Nunit is een unit test tool. De N staat voor DotNet variant van Java idee. Dus idee is gewoon gejat. Nunit is heel simpel toe te passen. Maak in je project file voor elke directory een extra directory aan met de naam test. Schrijf hier in Test classes die beginnen met een compiler directive. Maak ook een nieuwe solution configuratie aan die deze compiler directive ondersteunt.&lt;br /&gt;&lt;br /&gt;Voorbeeld van een comiler directive&lt;br /&gt;#if  UNIT_TEST&lt;br /&gt;&lt;br /&gt;Aan de testclass geef je het atribuut [TestFixture] mee&lt;br /&gt;Voeg een referentie naar het Unit framework toe plus de using&lt;br /&gt;using NUnit.Framework;&lt;br /&gt;&lt;br /&gt;Aan de testmethode geeft je het attribuut [Test] mee&lt;br /&gt;En eventueel geef je de verwachte fout van een test via een attribuut aan een testmethode mee&lt;br /&gt;[ExpectedException(typeof(ArgumentException))]&lt;br /&gt;&lt;br /&gt;Via assert statements zoals assert.IsTrue(condition) kun checken of er gebeurt wat je verwacht. Deze assert statements plus declaraties en initialisaties vormen samen je testscenario.&lt;br /&gt;&lt;br /&gt;De te testen code begint met een method met attribute [Test]. Daarnaast kunnen nog Expected error attributen meegegeven worden. Stel je wil zeker weten of 12/0 een Arithmitic overflow geeft. Dan neem je dit als Expected exception attribuut aan de methode mee. Blijkt het om een DiveByZero exception te gaan faalt de test. Dit betekend of de test herscrhijven of de code herschrijven. Dit is ook het gevaar. Unit tests worden te snel aan de code aangepast of omgekeerd. In plaats van de juiste error te throwen wordt dan stiekem een Arithmitic overlfow gethrowd ipv divebyzero exception. Dat is natuurlijk niet de bedoeling van unit tests.&lt;br /&gt;&lt;br /&gt;Met de meegelevede Nunit Gui kun je de tests laten uitvoeren. Compileer de applicatie en selecteer dll or exe met deze Nunit Gui applicatie. Afhankelijke dll's dienen in dezelfde directory aanwezig te zijn. Rode en Groene bolletjes geven na de run aan of het een en ander gelukt is of niet. In de output window staat waarom.&lt;br /&gt;&lt;br /&gt;Aangezien Nunit niet met een toppie interface komt, hebben anderen een plugin geschreven genaamd TestDriven. Deze kun je op de site http://www.testdriven.net/HomePage.htm downloaden. Het is een plugin om unit tests op je PC te starten. Deze plugin nestelt zich in visual studio zodat je een class of methode ook in debug mode kan testen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-111814606881598465?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/111814606881598465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=111814606881598465&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/111814606881598465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/111814606881598465'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2005/06/unit-test.html' title='Unit test'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10549483.post-111246290480531059</id><published>2005-04-02T09:16:00.000-08:00</published><updated>2005-04-05T13:55:37.046-07:00</updated><title type='text'>Login control</title><content type='html'>It's four weeks now, that I am back from holiday. My current work project ends soon. It's a little bit funny, but I have not so much to do at the moment. The customer testing days are used not to test the application (they don't). So a few bugs are reported so far. &lt;br /&gt;I've taken a look at the login control components of asp.net 2. All seem to be fine. Now I am started to edit the templates of the CreateUserWizard. I want the user the enter his/her birthday to create an account. Also I thought a dutch button would be better. Changing the control, works best if changing the text properties of the (whole) control. I added my own buttons in de de stepwizard template. The buttons needs then to be named precisely such as StepPreviousButton, FinischCompleteButton etc... I even found out that controls on the first page can not be reached by code. I also found out that the continue button is on every page. So to do something with the controls on a page the continue button has to be implemented and the activestepindex property has to be checked. I also noticed that it's handy to automatically add a user to a role when finishing the login. So on the last wizardstep page this should be handled. There is also a canceldestionation and a finishdestination URL property. This may lead the user someday away from this control. The having of a continuedestionURL property supprised me. So the next step of a wizard leads to a new page?.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10549483-111246290480531059?l=ms-dotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ms-dotnet.blogspot.com/feeds/111246290480531059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10549483&amp;postID=111246290480531059&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/111246290480531059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10549483/posts/default/111246290480531059'/><link rel='alternate' type='text/html' href='http://ms-dotnet.blogspot.com/2005/04/login-control.html' title='Login control'/><author><name>Dieder Timmerman</name><uri>http://www.blogger.com/profile/04653528527402792896</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
