Schema validation component

In my latest project we had a requirement to validate schemas, In several locations within the process flow schemas needed validation.

Now I know validation can be performed in an xml pipeline, but then again when looking in to the pipeline code using reflection validation happens using an XmlReader against the XSD schema, there are several benefits in writing a custom component.

The XmlReader takes in its constructor an XmlReaderSettings component, the XmlReaderSettings exposes an event we can subscribe to which will trigger if the schema validation fails, This allows to create an ESB fault message(we where using the ESB Exception management portal) without running within a try catch block, which is more preferment.

The XmlReaderSettings uses the XmlSchemaSet object to store the schemas it will validate against which allows the ability to cache the schemas and thus improve performance. Note that XmlSchemaSet is guaranteed to be thread safe only when used as a static field(singleton), all schemas that need validation must be loaded in to the XmlSchemaSet in the static constructor and thus create a caching effect.

The code is available here SchemaValidation.cs

Advertisements

Enumerating context properties

Enumerating the context properties of a BizTalk message can be useful when trying to solve an error in an orchestration.

I wrote the following method to our tracing component that will loop through the context properties of an XLANGMessage.

because the context properties are hidden within the XMessage object in the Microsoft.XLANGs.Core name space, I had to use reflection to unwrap  XMessage in order to expose the GetContextProperties() method.

Important:

This method uses the internal method “Unwrap” in the XMessage object that is NOT intended to be used by user code DO NOT USE this method in a production environment, I use it only for testing purposes and remove the call to the method when finished.

public void WriteMessageProperties(XLANGMessage message)
{
    try
    {
        StringBuilder sb = new StringBuilder();
        sb.Append(Environment.NewLine);
        if (message is Microsoft.XLANGs.Core.MessageWrapperForUserCode)
        {
            Microsoft.XLANGs.Core..MessageWrapperForUserCode mwu = (Microsoft.XLANGs.Core..MessageWrapperForUserCode)message;
            Microsoft.XLANGs.Core.XMessage xmessage = (Microsoft.XLANGs.Core.XMessage)mwu.GetType()
            .GetMethod("Unwrap", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
            .Invoke(mwu, null);
            if (xmessage != null)
            {
                System.Collections.Hashtable ht = xmessage.GetContextProperties();
                Microsoft.XLANGs.Core.XmlQNameTable tbl = new Microsoft.XLANGs.Core.XmlQNameTable(ht);
                foreach (System.Collections.DictionaryEntry dic in tbl)
                {
                    Microsoft.XLANGs.BaseTypes.XmlQName N = (Microsoft.XLANGs.BaseTypes.XmlQName)dic.Key;
                    sb.Append(N.Name + " : " + dic.Value + Environment.NewLine);
                }
            }
        }
        LogEntry entry = new LogEntry();
        entry.Message = sb.ToString();
        entry.Categories = new string[1] { sourceType };
        entry.Severity = System.Diagnostics.TraceEventType.Verbose;
        Logger.Write(entry);
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.ToString(), "Error");
    }
    finally
    {
        // Call Dispose on the XLANGMessage object 
        // because the message doesn't belong to the 
        // .NET runtime - it belongs to the MessageBox database 
        message.Dispose();
    }
}

Balls bouncing and colliding on the screen

Just a small graphical application i made in my free time.
The program has a ball form which is called in a loop from the void main method.

We catch the paint event which is where the ball is drawn:

private void BallForm_Paint(object sender, PaintEventArgs e)
{
    Width = Convert.ToInt32(radios * 2); //24;
    Height = Convert.ToInt32(radios * 2); //24;

    Graphics g = e.Graphics;
    g.Clear(Color.Cyan);
    g.FillPie(new SolidBrush(col), 0, 0, Width - 1, Height - 1, 0, 360);
    g.DrawArc(new Pen(Color.Black,2), 0, 0, Width - 1, Height - 1, 0, 360);
}

Gravity:
the balls are under the force of gravity there for always pulled down, to get this effect every tick  the Y vector decreased in just a bit which simulated gravity and can be modified to have a stronger gravitational pull if increased

double gravity = 0.1;
moveY += gravity;

also the X vector is changed to simulate fraction
moveX *= 0.75;

Collision:
balls that collide with one each other are calculated to bounce away in the opposite direction of the impact, in this case some physics is needed to calculate the direction of 2 collisions using the radios of the circles equation to find if one ball entered another balls radios space

double distIn = Math.Sqrt(Math.Pow((int)x1 - (int)x2, 2) + Math.Pow((int)y1 - (int)y2, 2));
m = (y2 - y1) / (x2 - x1);
double b = y1 - (m * x1);

and the velocity of the ball which absorbs the velocity from the ball it collided with
double difX = Math.Abs(oBall.moveX – moveX);
double difY = Math.Abs(oBall.moveY – moveY);

if right clicking on a ball a small menu will open and allow some functionality like make it bounce again(which will any way happen when the ball stops movement) the tricky part is to catch the right click event exactly when the pointer is over the ball good luck 🙂

here is the source code:

Visual studio 2005: BouncingBall-SRC.zip

focus tab items in a CAB workspace

In one of the projects i worked on we where implementing Microsoft CAB (Composite UI Application Blocks) one of the features of the CAB is the tab view workspace.

Problem:
Tab items (which in our application inherited from System.Windows.Forms.Control as one of its base classes) where created and added to the Infragistics.Practices.CompositeUI.WinForms.UltraTabWorkspace workspace from the work item class.
When the tab got focus by calling the Show(ByVal smartPart As Object) method on the SmartParts.IWorkspace workspace class,
the last control to have the focus did not get it back infect the focus was on the tab itself and not on one of its child controls(as we required).

for example if a tab had a Textbox as one of it’s child controls, when the focus is on the Textbox then we change to another tab and change back the focus
did not return to the Textbox(but stayed on the tab header itself)

there was no way to pick an event by the view after it was showed by the workspace,
so i had to inherit from the UltraTabWorkspace and override the OnSmartPartActivated method.

Another problem was inner controls that had their child controls stored in a panel.
This was solved by having each of those controls implement an interface IPanelControl which returned the panel property of that control.

Solution:
the solution was to iterate thru all controls and child controls(and panel child controls) and listen to their GotFocus event,
when it is invoked save a reference to that control so we can refocus it later
(another problem was controls that where added dynamically i solved by overriding the OnControlAdded method)

refocusing was done by overriding the method OnSmartPartActivated on the UltraTabWorkspace

here is the code:

class TabView : System.Windows.Forms.Control
{
    /// <summary>
    /// 'monitor the views control add flow
    /// </summary>
    /// <param name="e"></param>
    /// <remarks></remarks>
    protected override void OnControlAdded(System.Windows.Forms.ControlEventArgs e)
    {
        base.OnControlAdded(e);
        zSetFocusHandlers(e.Control);
        e.Control.ControlAdded += ControlAddedEvent;
        if ((e.Control) is IPanelControl && ((IPanelControl)e.Control).PanelControl != null)
        {
            ((IPanelControl)e.Control).PanelControl.ControlAdded += ControlAddedEvent;
        }
    }

    /// <summary>
    /// 'monitor the views child controls flow
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    /// <remarks></remarks>
    protected void ControlAddedEvent(object sender, System.Windows.Forms.ControlEventArgs e)
    {
        zSetFocusHandlers(e.Control);
        e.Control.ControlAdded += ControlAddedEvent;
        if ((e.Control) is IPanelControl && ((IPanelControl)e.Control).PanelControl != null)
        {
            ((IPanelControl)e.Control).PanelControl.ControlAdded += ControlAddedEvent;
        }
    }

    /// <summary>
    /// this is a recursive method, that will
    /// loop throw all child controls and add a handler for the focus event
    /// </summary>
    /// <param name="cnt"></param>
    /// <remarks></remarks>
    private void zSetFocusHandlers(Control cnt)
    {
        AddControlFocusHandler(cnt, false);
        foreach (Control cntm in cnt.Controls)
        {
            zSetFocusHandlers(cntm);
        }
    }

    /// <summary>
    /// 'add the focus event, her we can filter the controls that dont need handeling
    /// </summary>
    /// <param name="cnt"></param>
    /// <remarks></remarks>
    protected virtual void AddControlFocusHandler(Control cnt, bool Force)
    {
        if (Force || (cnt) is IFocusHandeling
            || (cnt) is TextBox
            || (cnt) is ComboBox
            || (cnt) is Button
            || (cnt) is ListBox
            || (cnt) is CheckBox
            || (cnt) is RichTextBox
            || (cnt) is Infragistics.Win.UltraWinGrid.UltraGrid
            || (cnt) is Infragistics.Win.UltraWinEditors.UltraTextEditor)
        {
            cnt.GotFocus += Control_GotFocusEvent;
        }
    }

    /// <summary>
    /// 'when a control got a focus remember it for future use
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    /// <remarks></remarks>
    protected void Control_GotFocusEvent(object sender, System.EventArgs e)
    {
        ControlToFocus = (Control)sender;
    }

    protected Control ControlToFocus;

    /// <summary>
    /// this happens when the smart part is activated, it origens in the Tab control
    /// </summary>
    /// <remarks></remarks>
    public void SmartPartActivated()
    {
        if (ControlToFocus != null)
        {
            //calling a thread that will manage the focusing of the last focusd control
            FocusThread = new Threading.Thread(zFocusLastControl);
            FocusThread.Start();
        }
    }

    private Thread FocusThread;
    private bool FocusThreadTerminate;

    /// <summary>
    /// this method will loop and try to focus the last focusd control until the thread is aboarted or loop is finished
    /// this method is running in a nother thread
    /// </summary>
    /// <param name="obj"></param>
    /// <remarks></remarks>
    private void zFocusLastControl(object obj)
    {
        try
        {
            FocusThreadTerminate = false;
            for (int i = 0; i <= 10; i++)
            {
                zSetFocusFocus();
                if (FocusThreadTerminate) break;

                Threading.Thread.Sleep(200);
                //this code will normally never be reached
            }
        }
        catch (Threading.ThreadAbortException exa)
        {
        }
        //this is the thread exception that will be thrown when thread is aborted by the application
        catch (Exception ex)
        {
        }
        //any other error will apear here
    }

    /// <summary>
    /// try to set the focus to the control
    /// if succeeded then abort the calling thread else continue wating and try again in the next cicle
    /// </summary>
    /// <remarks></remarks>
    private void zSetFocusFocus()
    {
        if (ControlToFocus == null)
        {
            //FocusThread.Abort()
            FocusThreadTerminate = true;
            return;
        }
        if (ControlToFocus.InvokeRequired)
        {
            //ControlToFocus.BeginInvoke(New Threading.ThreadStart(AddressOf setFocusFocus))
            ControlToFocus.Invoke(new Threading.ThreadStart(zSetFocusFocus));
        }
        else if (ControlToFocus.CanFocus())
        {
            ControlToFocus.Focus();
            //FocusThread.Abort()
            FocusThreadTerminate = true;
        }
    }
}

public interface IPanelControl
{
    Control PanelControl
    {
        get;
    }
}

/// <summary>
/// inherited UltraTabWorkspace object in order to get access to the override methods
/// </summary>
/// <remarks>the reason is to set the TabKey property when the a workItem is created</remarks>
public class UltraTabWorkspace : Infragistics.Practices.CompositeUI.WinForms.UltraTabWorkspace
{

    protected override void OnSmartPartActivated(Microsoft.Practices.CompositeUI.SmartParts.WorkspaceEventArgs e)
    {
        base.OnSmartPartActivated(e);
        if (e.SmartPart != null)
        {
            ((TabView)e.SmartPart).SmartPartActivated();
        }
    }
}

control that grows

Its a nice graphical display and makes it comfortable to use having a control like a Textbox Listbox or even a Gridview grow when focused or hovered by the mouse, i made a small class that will manage that.

Passing any control to the GrowManager will allow a control to expand on certain events (OnMOuseOver, OnFocus etc…) the size of growth can be determine on the constructor or on the properties exposed by the GrowManager class.

here’s the code:

public class GrowManager
{
    // Methods
    public GrowManager(Control owner)
    {
        this.Owner = owner;
        this.Owner.MouseEnter += new EventHandler(this.Owner_MouseEnter);
        this.Owner.MouseLeave += new EventHandler(this.Owner_MouseLeave);
        this.Owner.Enter += new EventHandler(this.Owner_Enter);
        this.Owner.Leave += new EventHandler(this.Owner_Leave);
    }

    public GrowManager(Control owner, int MaxHeight, int MaxWidth)
    {
        this.Owner = owner;
        this._MaxHeight = MaxHeight;
        this._MaxWidth = MaxWidth;
        this.Owner.MouseEnter += new EventHandler(this.Owner_MouseEnter);
        this.Owner.MouseLeave += new EventHandler(this.Owner_MouseLeave);
        this.Owner.Enter += new EventHandler(this.Owner_Enter);
        this.Owner.Leave += new EventHandler(this.Owner_Leave);
    }

    ~GrowManager()
    {
        this.Owner.MouseEnter -= new EventHandler(this.Owner_MouseEnter);
        this.Owner.MouseLeave -= new EventHandler(this.Owner_MouseLeave);
        this.Owner.Enter -= new EventHandler(this.Owner_Enter);
        this.Owner.Leave -= new EventHandler(this.Owner_Leave);
    }

    private void Grow()
    {
        if (!this.isInGrowthMode)
        {
            int Dif = 0;
            int n = 0;
            this.Owner.SuspendLayout();
            this._OrigSize = this.Owner.Size;
            this._origLocation = this.Owner.Location;
            int growToHeight = this._MaxHeight;
            int growToWidth = this._MaxWidth;
            int LocationX = this.Owner.Location.X;
            int LocationY = this.Owner.Location.Y;
            bool GrowVertical = false;
            bool GrowHorizontal = false;
            if ((growToHeight > this.Owner.Height))
            {
                LocationY = (int)(LocationY - ((growToHeight - this.Owner.Height) / 2));
                Dif = 0;
                if ((LocationY < 0))
                {
                    Dif = Math.Abs(LocationY);
                }
                if ((((this.Owner.Parent != null)) && (this.Owner.Parent.Height < (LocationY + growToHeight))))
                {
                    n = (Math.Abs((int)((LocationY + growToHeight) - this.Owner.Parent.Height)) + 8);
                    Dif = (int)((n > Dif) ? n : Dif);
                }
                if ((Dif > 0))
                {
                    growToHeight = (growToHeight - ((Dif * 2) + 2));
                    LocationY = (int)(this.Owner.Location.Y - ((growToHeight - this.Owner.Height) / 2));
                }
                GrowVertical = true;
            }
            if ((growToWidth > this.Owner.Width))
            {
                LocationX = (int)(LocationX - ((growToWidth - this.Owner.Width) / 2));
                Dif = 0;
                if ((LocationX < 0))
                {
                    Dif = Math.Abs(LocationX);
                }
                if ((((this.Owner.Parent != null)) && (this.Owner.Parent.Width < (LocationX + growToWidth))))
                {
                    n = (Math.Abs((int)((LocationX + growToWidth) - this.Owner.Parent.Width)) + 8);
                    Dif = (int)((n > Dif) ? n : Dif);
                }
                if ((Dif > 0))
                {
                    growToWidth = (growToWidth - ((Dif * 2) + 2));
                    LocationX = (int)(this.Owner.Location.X - ((growToWidth - this.Owner.Width) / 2));
                }
                GrowHorizontal = true;
            }
            if (GrowVertical)
            {
                this.Owner.Height = growToHeight;
            }
            if (GrowHorizontal)
            {
                this.Owner.Width = growToWidth;
            }
            this.Owner.Location = new Point(LocationX, LocationY);
            this.Owner.BringToFront();
            this.isInGrowthMode = true;
            this.Owner.ResumeLayout(false);
        }
    }

    private void GrowBack()
    {
        this.Owner.Location = this._origLocation;
        this.Owner.Size = this._OrigSize;
        this.Owner.SendToBack();
        this.isInGrowthMode = false;
    }

    private void Owner_Enter(object sender, EventArgs e)
    {
        this.Grow();
    }

    private void Owner_Leave(object sender, EventArgs e)
    {
        this.GrowBack();
    }

    private void Owner_MouseEnter(object sender, EventArgs e)
    {
        this.Grow();
        if (_FocusOnMouseEnter) Owner.Focus();
    }

    private void Owner_MouseLeave(object sender, EventArgs e)
    {
        this.GrowBack();
    }

    // Properties
    public bool FocusOnMouseEnter
    {
        get { return _FocusOnMouseEnter; }
        set { _FocusOnMouseEnter = value; }
    }

    public int MaxHeight
    {
        get { return this._MaxHeight; }
        set { this._MaxHeight = value; }
    }

    public int MaxWidth
    {
        get { return this._MaxWidth; }
        set { this._MaxWidth = value; }
    }

    // Fields
    private bool _FocusOnMouseEnter;
    private int _MaxHeight;
    private int _MaxWidth;
    private Point _origLocation;
    private Size _OrigSize;
    private bool isInGrowthMode;
    protected Control Owner;
}