Thursday, June 12, 2003

.NET Posters

.NET Posters

Ever wanted one of those cool VS.NET object model posters you see on other developers walls? Have a 36" wide HP InkJet sitting unused down the hall since the last time you printed out that 1500 table ERD diagram? Well solve both problems with one link: http://msdn.microsoft.com/vstudio/productinfo/posters/download.aspx

Thursday, June 12, 2003 1:56:42 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 

  Monday, June 09, 2003

Validation and Form Close

Validation and Form Close

Ran into a weird one today.  We have a windows forms application that uses the validating event on it's controls.  When the user clicks the close box (red x) in the corner we want to prompt whether they would like to save and then close the form.

The validators cause problems with this.  Clicking on the close box causes validation to run. First blush you think no problem, I will set CausesValidation on the form to false.  Whoa!  The Validating event still fires.  It appears that the close box always causes validation. Next you think I will override OnClosing() and ask whether they want to save before calling the base implementation thus only allowing the Validating events to fire if they are saving.  Wrong again.  Validating fires before OnClosing!

So here is the hack I came up with.  Override WndProc in the form and look for the WM_CLOSE message.  If you receive it then set a protected member on the form to indicate it is currently closing.  I have this hidden in a base class that exposes the member as a read only property.

Here is some sample code:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace ValidationTest
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.TextBox textBox2;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        public Form1()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            //
            // TODO: Add any constructor code after InitializeComponent call
            //
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.textBox2 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(80, 96);
            this.textBox1.Name = "textBox1";
            this.textBox1.TabIndex = 0;
            this.textBox1.Text = "textBox1";
            this.textBox1.Validating += new System.ComponentModel.CancelEventHandler(this.textBox1_Validating);
            // 
            // textBox2
            // 
            this.textBox2.Location = new System.Drawing.Point(80, 128);
            this.textBox2.Name = "textBox2";
            this.textBox2.TabIndex = 1;
            this.textBox2.Text = "textBox2";
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.textBox2);
            this.Controls.Add(this.textBox1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        // Constant for WM_CLOSE
        private const int WM_CLOSE = 16;
        // flag to indicate we are closing
        private bool m_bFormClosing = false;

        protected virtual bool FormClosing
        {
            get { return m_bFormClosing; }
        }

        private void textBox1_Validating(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // Bail out if the form is in the process of closing
            if(FormClosing)
                return;

            // Do my normal validation
            if(this.textBox1.Text == "invalid")
            {
                e.Cancel = true;
                MessageBox.Show("Invalid entry");
            }
        }

        protected override void WndProc(ref Message m)
        {
            // Check for the closing message
            if(m.Msg == WM_CLOSE)
                // Set our flag
                m_bFormClosing = true;

            // Call the base
            base.WndProc (ref m);
        }
    }
}

 

Wow that is ugly!  If anyone knows of a good C# -> HTML converter that works with Radio send me a pointer at mailto:ckinsman@vergentsoftware.com. This is from http://www.manoli.net/csharpformat/

Monday, June 09, 2003 6:58:19 AM (Pacific Standard Time, UTC-08:00)   #      Comments [1]  
 

  Monday, April 07, 2003

Managed Wrapper for BITS

Managed Wrapper for BITS

BITS is a pretty cool background transfer service that does the hard work of actually determining when your network connection is idle to transfer files. A managed wrapper for the API just became available on MSDN.

Monday, April 07, 2003 9:38:38 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 
Blast from the Past

Blast from the Past

Keith brings up writing certification exams for Microsoft.  We both did this for a while and became SMEs (Subject Matter Experts) in the terminology of the team at the time.  It was interesting to get some insight into the truly bizarre way that importance is assigned to topics in those tests.  The way correct answers were determined was sometimes even more bizarre.  One of the main reasons that I stopped the whole exam treadmill years ago. 

I still laugh when I remember back to arguing with Ken and Mike over whether or not Access questions should be on a Windows Architecture exam...

Sunday, April 06, 2003 11:49:56 PM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 

  Wednesday, March 26, 2003

.NET 1.1 Breaks ChainStream

.NET 1.1 Breaks ChainStream

Well we have been working hard on converting our 1.0 code base to 1.1.  We keep running into little things that are breaking our code though.  The latest is a breaking change in ChainStream.  We had a compression stream that we were running on top of our web services. In .NET 1.1 some new code (SoapServerProtocolHelper) was introduced that attempts to seek the stream closest to .NET without checking the CanSeek property.  Essentially what this means is that whereas non-seekable streams were legal in 1.0 they are no longer legal in 1.1.  Kind of kills some of the utility of ChainStream since it means that you pretty much have to buffer the whole request or figure out how to just buffer some of the envelope so you can seek back when requested. Here is the disassembly courtesy of Anakrino:

internal static SoapServerProtocolHelper GetHelper(SoapServerProtocol protocol) {

SoapServerMessage local0;

long local1;

XmlTextReader local2;

string local3;

SoapServerProtocolHelper local4;

local0 = protocol.Message;

local1 = local0.Stream.Position;

local2 = SoapServerProtocolHelper.GetXmlTextReader(local0.ContentType, local0.Stream);

local2.MoveToContent();

local3 = local2.NamespaceURI;

local4 = SoapServerProtocolHelper.GetHelper(protocol, local3);

local0.Stream.Position = local1;

return local4;

}

The killers are the lines that attempt to set the position...

Wednesday, March 26, 2003 12:45:04 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 

  Tuesday, March 25, 2003

Radio Fixed

Radio Fixed!

Radio is working again finally!  Thanks to Lawrence Lee.

Tuesday, March 25, 2003 8:31:15 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 

  Wednesday, March 19, 2003

.NET Memory Profiler

.NET Memory Profiler

Great tool that I found that helped us find a pernicious "memory leak". http://www.scitech.se/memprofiler/ offers a memory profiler that doesn't slow down your application as much as the Borland memory profiler but still allows you to compare memory snapshots, find objects that aren't being disposed and potentially trace down the root references of those objects.

Wednesday, March 19, 2003 3:51:57 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 
WildGrape NewsDesk and DotNetWebLogs

WildGrape NewsDesk and DotNetWebLogs

I am reminded why I have yet to leave Radios aggregator.  As I am reading the blogs on http://dotnetweblogs NewsDesk continues to show blogs I have read as new every time I start it up!  Radio OTOH is smart enough to only show items that are truly new.  I have no idea how or why they differ but I certainly prefer the way Radio does it.

Wednesday, March 19, 2003 1:50:56 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 

  Thursday, February 13, 2003

SourceGear Vault

SourceGear Vault

I don't mention products here very often but this one has me excited.  I have hated Visual SourceSafe for quite some time now.  I am sure that many of you share my frustrations with it.  SourceGear the makers of the popular SourceOffsite add-in for VSS shipped Vault at the VSLive show in San Francisco this week.  Vault is a complete replacement for VSS using SQL Server as a back end store and Web Services/ASP.NET as a transport mechanism!  It is a purely managed solution that replicates almost 100% of VSS functionality. I have no connection to the company but I have already ordered a copy.  They have a great starter pack at $599 for 5 developers.  I have just started using this product and I have high hopes for it.  Check it out.

Thursday, February 13, 2003 9:48:00 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 

  Friday, January 10, 2003

FONT FaceVerdanaGenevaArialHelveticaSans

Read Only Application Object

Requirement:

Pre-Load the ASP.NET Application object and don’t allow other pages in your project to add/modify/delete. Basically, make Application read-only.

Solution:

         private void SetApplicationReadOnlyStatus( bool state ) {
                  Type type = Application.GetType().BaseType;
                  PropertyInfo readPropInfo = type.GetProperty("IsReadOnly",  BindingFlags.NonPublic | BindingFlags.Instance) ;
                  if( readPropInfo != null ) {
                        readPropInfo.SetValue( Application,Convert.ChangeType(state,readPropInfo.PropertyType ) ,null);
                  }
            }
            private void Page_Load(object sender, System.EventArgs e) {
                  Application["MyKey"] = "myValue";
                  // Set application to readonly so that we will not allow any changes.
                  SetApplicationReadOnlyStatus( true );
                  try
                  {
                        // Try setting a value 
                        Application["MyKey"] = "New value";
                        Response.Write("You won't see this");
                  }
                  catch(Exception ex) {
                        // You'll end up here
                        Response.Write(ex.Message);
                }
            }

Thanks to Sairama for the code!

Set the ASP.NET Application Object to Read-Only. [Scott Hanselman's Weblog] Friday, January 10, 2003 4:20:52 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 


Administration
Sign In