Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Internal Supply Chain Management System, Visibility

0.00/5 (No votes)
9 Oct 2009 1  
Internal supply chain management system's objective is to visualize organization's activities and events spawn during its work flow and offers panoramic view of upstream and downstream activities

Introduction  

Internal supply Chain, visibility via 200 plus 3D Chart Reports Part II

This article focuses on the visibility of internal supply chain management process. Its primary objective is to visualize activity and event spawn during work flow and offers panoramic view of upstream and downstream activities. It constitutes inbound, outbound and production operations, and can be segmented into Raw material, work in process and finished goods with their intrinsic operations.

Visibility

In supply chain management information’s visibility is pivotal. System provided context based perpetual inventory by date and material, and history of perpetual inventory as well. Canvas legend provides spectrum to distinguish and visualizes perpetual inventory of refined context (filtered). To elaborate view of perpetual inventory material can be extracted by hovering mouse over the concerned bar.

Inbound Operation Events

Raw material inbound events are inspected by checking inbound Event check box. Hence material events are extracted associated with refined context (filtered). Detail view is obtained by hovering mouse over concerned event bar.

Material Inbound and Production Operation Transition

Panoramic view material inbound and operation transition has two preliminary paths or stages. First one starts from in transit, it corresponds to the situation where material purchase order has been dispatched and is waiting for the material to be delivered. When in transit material is received, it is recorded in material inventory. When in stock inventory is contaminated in any way, then inbound material dispose or waste operation is performed which transforms the material to waste state. Material operation transition convolutes with production operation. There are two operation paths, both of them are initiated by invoking a job. When job status is set to Pending material stock is reserved for the job and is dispatched for production when job status changes to current. It can be set to current Job when job is going to be in manufacturing phase directly. At completion of manufacturing process of the job, status will be set to Completed and produced finished goods will proceed towards QA department and further into finished goods inventory.

Work in Progress Production Operations

Work in progress is a middle layer between raw material and finished goods operational layer thus it acted as buffer between them binding rather then joining them together by Job specification. Job specification constitutes Finished goods that needed to be produced during production operation and Raw material consumed to produced goods, Job adheres two status, the first one is pending job which signifies material stock has been reserved but is not dispatched to manufacturing phase, thus there is no Physical transition in material stock. This delay may be due to unavailability of material stock at that particular instance of establishment of job.

Visibility

Jobs and their diverse phase can be viewed at real time, according to date refine context. The job status is represented by spectrum, which is associated with pending, manufacturing and QA Phase. In work in progress view, each color corresponds to respective event. Each event detail is viewed by hovering mouse over the concerned event. This establishes jobs panoramic view.

Production Operation Events

Change in status of job generates production events represented by color spectrum which are associated with pending, manufacturing and QA phase. Each spectrum color corresponds to event as well, besides job status. Each event detail can be viewed by hovering mouse over the concerned event bar.

Transition of Production Operation

Operation transition convolutes with production operation. There are two operation paths, both of them are initiated by invoking a job. When job status is set to Pending Job, it shows job will be executed at later time. It can be set to current Job when job is going to be in manufacturing phase. At completion of manufacturing process of the job, status will be set to Completed and produced finished goods will proceed towards QA department and further into finished goods inventory.

Finished Goods Outbound and Production Operations

The system contours internal work flow and finished goods. Finished goods are value added inventory, which consume non-value added product (raw material). Operations performed by this segment alter material’s perpetual inventory.

Visibility

In supply chain management information’s visibility is pivotal. It provides context perpetual inventory by date and goods, and history of perpetual inventory as well. Canvas legend provides spectrum to distinguish and visualizes perpetual inventory of that refined context. To elaborate view of perpetual inventory goods can be extracted by hovering mouse over the concerned bar.

Outbound Operation Events

Finished goods outbound events are inspected by checking Event check box. Hence material events are extracted associated with refined context. Detailed view of it is obtained by hovering mouse over the concerned event bar.

Finished Goods Outbound and Production Operation Transition

Panoramic view finished goods outbound and operation transition has two preliminary paths or stages. First one starts from Pending Phase, it corresponds to the situation where material is reserved for production, it is also called pending job. When material is received and placed in material inventory, at appropriate time job is initiated which leads to subsequent stage that is manufacturing phase. After completion of the job, finished product is produced which is transit into finished goods inventory. When in stock inventory is contaminated in any way, then outbound finished goods dispose or waste operation is performed which transforms the material to waste.

Inner Working

Bars.cs class is the bread and butter of this application. It is derived from System.Windows.Forms.Control class. It represents work process in respect of time, Event in respect of date and quantity and perpetual inventory in respect of quantity and date. Events which contribute to visualization are OnPaintBackground, Bar_MouseMove, OnMouseClick and Bar_MouseLeave methods.

OnPaintBackground

This method draws bar user interface. It performs its functionality in step and calls MakeScale, IdentifyBarContext, GenerateCurrentContextBarResutset and GenerateBars respectively. It consumes barArrayList to draw bars on bar frame which is populated at GenerateCurrentContextBarResutset method call.

string filter = "";
Bar[] barArray;
ArrayList barArrayList;
float temp = 0;
private static Mutex mut = new Mutex();
System.Data.DataRow[] rows;

protected override void OnPaintBackground(PaintEventArgs pevent)
{
     mut.WaitOne();
     pevent.Graphics.SmoothingMode =Systtem.Drawing.Drawing2D.SmoothingMode.AntiAlias;
     Rectangle translateRect = this.Bounds;
     PaintEventArgs pe = new PaintEventArgs(pevent.Graphics, translateRect);
     this.InvokePaintBackground(this.Parent, pe);
           
     // calibrate scale on the bar frame
     MakeScale(pevent);
     // contains all bargrid's bar data
     barArrayList = new ArrayList();
            
           
     // user to shift scale initial reference point
     temp = (m_ValueDifference * 100) * m_ValuePerPixel;
          
     if ( Form1.data != null)
     {
          System.Windows.Forms.Control cont = 
          this.Parent.Controls.Find("Tag", true)[0];
          cont.BackColor = System.Drawing.SystemColors.Control;
          cont.ForeColor = Color.Black;

          if (!IdentifyBarContext(cont))
              return;
          GenerateCurrentContextBarResutset(cont);
      }
      else
      // data is not initialized abort no need to go further
      return;  

      GenerateBars(pevent); 
      mut.ReleaseMutex();
}

MakeScale

OnPaintBackground method MakeScale method. This method calibrates scale on bar frame according to current selected dimension. Its purpose is to enhance scale reading on bar frame.

// Celebrated bar frame
protected void MakeScale(PaintEventArgs pe)
{
      FindFontBounds();
      Bitmap Bitmap= new Bitmap(Width, Height, pe.Graphics);
      Graphics ggr = Graphics.FromImage(Bitmap);
      ggr.FillRectangle(new SolidBrush(System.Drawing.Color.Transparent), 
		ientRectangle);
      ggr.SmoothingMode = SmoothingMode.HighQuality;
      ggr.PixelOffsetMode = PixelOffsetMode.HighQuality;
      GraphicsPath gp = new GraphicsPath();
      ggr.SetClip(ClientRectangle);

      String valueText = "";
      SizeF boundingBox;
      Int32 counter1 = 0;
      Int32 scaleValueUnit = 0;
      Int32 scaleTemValueUnit = 0;
      Int32 scaleUnit = 0;

      while (scaleUnit <= 720)
      {
            ggr.DrawLine(new Pen(System.Drawing.Color.Gray, 2),
            (Single)scaleValueUnit,
            (Single)0,
            (Single)scaleValueUnit,
            (Single)35);
            valueText = "";
            boundingBox = ggr.MeasureString(valueText, 
            	Font, -1, StringFormat.GenericTypographic);
            scaleUnit++;
            scaleTemValueUnit = Convert.ToInt32(scaleTemValueUnit + 
		_ValuePerPixel * 10));
            scaleValueUnit = Convert.ToInt32(scaleValueUnit + (100 * m_ValuePerPixel));
            counter1++;
      }

      pe.Graphics.DrawImageUnscaled(Bitmap, 0, 0);
      pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
      pe.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
}

IdentifyBarContext

After calibrating bar frame IdentifyBarContext method is called. This method identifies context of the bar for which bars need to be drawn. MainForm.data is populated by MainForm, but it contain records of MainForm context and is not appropriate for bar context. This method filters down the record for current bar context.

// identifying current bar context 
bool IdentifyBarContext(System.Windows.Forms.Control cont)
{
      switch (perspective_ID)
      {
            // Raw material current bar context 
            case 0:
            if (option_ID == 0)
                  filter = " Goods_ID =" + iD;
            if (option_ID == 1)
                  filter = " Date =  #" + cont.Text + "#";
            rows = MainForm.data.Tables["GoodsCurrent"].Select(filter); 
            break;

            // Work in progress current bar context
            case 1:
                  filter = " Job_ID = " + iD;
                  rows = MainForm.data.Tables["JobByDate"].Select(filter); 
            break;

            // Finished goods current bar context
            case 2:
            if (option_ID == 0)
                  filter = " Goods_ID =" + iD;
            if (option_ID == 1)
                  filter = " Date =  #" + cont.Text + "#";
            rows = MainForm.data.Tables["GoodsCurrent"].Select(filter); 
            break;
      }
      return true;
} 

GenerateCurrentContextBarResutset

In subsequent step, GenerateCurrentContextBarResutset method is called. It generates resultset corresponding to refined context. It assigns color to each bar’s state, phase or transition.

Non-Event Raw Material resultsets by Date

Generation of raw material and job resultset by date will be discussed. In raw material, there are two more scenarios one is non-Event (perpetual inventory) and Event scenario. It quantifies the inventory by allocating length and location of concerned bar.

#region Generate non Event raw material resultsets by date
if (!is_Event)
{
      if (rows.Length == 0)
      {
            DataAccess.Access ac = new InventorySys.DataAccess.Access();
            rows = ac.RawMaterialSingleCurrent( iD
, this.Parent.Controls.Find("Date", true)[0].Text).Tables[0].Select();
      }

      barArray = new Bar[5];
      barArray[0].initial_Point = 0;
      barArray[0].ID = Convert.ToInt32(rows[0]["Goods_ID"]);
      // Incoming current
      if (((Convert.ToInt32(rows[0]["Incomming_Current"])) - temp) > 3)
      {
            barArray[0].final_Point =     
            (Convert.ToInt32(rows[0]["Incomming_Current"]) -   Convert.ToInt32
            (rows[0]["Outgoing_Finished"]) - 
            Convert.ToInt32(rows[0]["Outgoing_Expected"]) – 
            Convert.ToInt32(rows[0]["Outgoing_Waste"] ) -     
            Convert.ToInt32(rows[0]["Outgoing_InProcess"]) 
            - temp )* m_ValuePerPixel ;
            barArray[0].color = Color.Green;
            if( barArray[0].final_Point > 1 )
                  barArrayList.Add(barArray[0]);
      }
      else
      {
            barArray[0].final_Point = 0;
      }

      // Incoming Expected
      barArray[1].initial_Point = barArray[0].final_Point++;
      barArray[1].ID = Convert.ToInt32(rows[0]["Goods_ID"]);
      if (((Convert.ToInt32(rows[0]["Incomming_Expected"])) - temp) > 3)
      {
            barArray[1].final_Point = barArray[1].initial_Point +
            ((Convert.ToInt32(rows[0]["Incomming_Expected"]) 
            - temp) * m_ValuePerPixel);
            barArray[1].color = Color.Orange;
            if (barArray[1].final_Point > 1)
                  barArrayList.Add(barArray[1]);
      }
      else
      {
            barArray[1].final_Point = barArray[1].initial_Point;
      }

      // Outgoing Expected
      barArray[2].initial_Point = barArray[1].final_Point++;
      barArray[2].ID = Convert.ToInt32(rows[0]["Goods_ID"]);
      if (((Convert.ToInt32(rows[0]["Outgoing_Expected"])) - temp) > 3)
      {
            barArray[2].final_Point = barArray[2].initial_Point + 
            ((Convert.ToInt32(rows[0]["Outgoing_Expected"]) 
            - temp) * m_ValuePerPixel);
            barArray[2].color = Color.DarkBlue;
            if (barArray[2].final_Point > 1)
                  barArrayList.Add(barArray[2]);
      }
      else
      {
            barArray[2].final_Point = barArray[2].initial_Point;
      }

      // Outgoing In-Process
      barArray[3].initial_Point = barArray[2].final_Point++;
      barArray[3].ID = Convert.ToInt32(rows[0]["Goods_ID"]);
      if (((Convert.ToInt32(rows[0]["Outgoing_InProcess"])) - temp) > 3)
      {
            barArray[3].final_Point =  barArray[3].initial_Point 	
+ (Convert.ToInt32(rows[0]["Outgoing_InProcess"]) 
- temp) * m_ValuePerPixel;;
            barArray[3].color = Color.Yellow;
            if (barArray[3].final_Point > 1)
            {
                  barArrayList.Add(barArray[3]);
            }
      }
}
#endregion 

Event Raw Material resultsets by Date

In event scenario, all transition physical or non-physical are presented in palettes, and its quantity is represented by bar’s length.

#region  Generate Event raw material resultsets by date
if (is_Event)
{
      barArray = new Bar[rows.Length];
      float temp_Initial_Point = 0;
      for (int i = 0; i < rows.Length; i++)
      {
            barArray[i].final_Point =  temp_Initial_Point + 
            (Convert.ToInt32(rows[i]["Unit"]) - temp )  * m_ValuePerPixel;;;
            barArray[i].initial_Point = temp_Initial_Point - temp;
            temp_Initial_Point = barArray[i].final_Point + temp;       
            barArray[i].ID = Convert.ToInt32(rows[i]["Transaction_ID"]);

      // Incoming Expected
      if (Convert.ToInt32(rows[i]["Transaction_Type_ID"]) == 1 && 
      Convert.ToInt32(rows[i]["Transaction_Status_ID"]) == 2)
      {
            barArray[i].color = Color.Orange;
      }

      // Incoming Current
      if (Convert.ToInt32(rows[i]["Transaction_Type_ID"]) == 1 && 
      Convert.ToInt32(rows[i]["Transaction_Status_ID"]) == 1)
      {
            barArray[i].color = Color.Green;
      }

      // outgoing Expected 
      if (Convert.ToInt32(rows[i]["Transaction_Type_ID"]) == 2 && 
      Convert.ToInt32(rows[i]["Transaction_Status_ID"]) ==2  )
      {
            barArray[i].color = Color.DarkBlue;
      }

      // outgoing In-Process
      if (Convert.ToInt32(rows[i]["Transaction_Type_ID"]) == 2 && 
      Convert.ToInt32(rows[i]["Transaction_Status_ID"]) == 3)
      {
            barArray[i].color = Color.Yellow;
      }

      // Outgoing Finished
      if (Convert.ToInt32(rows[i]["Transaction_Type_ID"]) == 2 && 
      Convert.ToInt32(rows[i]["Transaction_Status_ID"]) == 5)
      {
            barArray[i].color = Color.Black;
      }

      // Outgoing Waste
      if (Convert.ToInt32(rows[i]["Transaction_Type_ID"]) == 2 && 
      Convert.ToInt32(rows[i]["Transaction_Status_ID"]) == 6)
      {
            barArray[i].color = Color.Red;
      }

      if (barArray[i].final_Point > 1)
            barArrayList.Add(barArray[i]);
      }
}
#endregion

Job Event resultset by Date

In this event based scenario, status is presented in colors, and time which it consumes is represented by bar’s length and location on the bar frame.

#region Generate job resultsets by date
TimeSpan ts = new TimeSpan();
ts = DateTime.Parse(rows[0]["Start_Date_Time"].ToString()) - 
	DateTime.Parse(Bars.m_Start_Date);
Bar[] barArrayFirst = new Bar[1];
barArrayFirst[0].initial_Point = (ts.Days + 1) * (100 * m_ValuePerPixel) + 
	(ts.Hours * Convert.ToSingle(2.5 * m_ValuePerPixel));
ts = DateTime.Parse(rows[0]["End_Date_Time"].ToString()) - 
	DateTime.Parse(Bars.m_Start_Date);
barArrayFirst[0].final_Point = (ts.Days + 1) * (100 * m_ValuePerPixel) + 
	(ts.Hours * Convert.ToSingle(2.5 * m_ValuePerPixel)); ;
barArrayFirst[0].ID = Convert.ToInt32(rows[0]["Job_ID"]);
barArrayFirst[0].Job_Transaction_ID = 0;
barArrayFirst[0].Is_Final_Job_Status = true;

// Expected
if (Convert.ToInt32(rows[0]["Status_ID"]) == 2)
{
      cont.BackColor = Color.Orange;
      cont.ForeColor = Color.Black;
      barArrayFirst[0].color = Color.Orange;
}

// In-Progress
if (Convert.ToInt32(rows[0]["Status_ID"]) == 3)
{
      cont.BackColor = Color.Green;
      cont.ForeColor = Color.White;
      barArrayFirst[0].color = Color.Black;
}

// Finished
if (Convert.ToInt32(rows[0]["Status_ID"]) == 5)
{
      cont.BackColor = Color.Yellow;
      cont.ForeColor = Color.Black;
      barArrayFirst[0].color = Color.DimGray;
}

// Waste
if (Convert.ToInt32(rows[0]["Status_ID"]) == 6)
{
      cont.BackColor = Color.Red;
      cont.ForeColor = Color.White;
      barArrayFirst[0].color = Color.Red;
}

if (barArrayFirst[0].final_Point > 1)
      barArrayList.Add(barArrayFirst[0]);

rows = Form1.data.Tables["Job_TransactionByDate"].Select
	( "Job_ID = " + rows[0]["Job_ID"].ToString() );
barArray = new Bar[rows.Length];
for (int i = 0; i < rows.Length; i++)
{
      ts = DateTime.Parse(rows[i]["Start_Date_Time"].ToString()) 
      	- DateTime.Parse(Bars.m_Start_Date);

      barArray[i].initial_Point = ( (ts.Days + 1) * (100 * m_ValuePerPixel)) 
      	+ (ts.Hours * Convert.ToSingle(2.5 * m_ValuePerPixel));                         
      ts = DateTime.Parse(rows[i]["End_Date_Time"].ToString()) 
      	- DateTime.Parse(Bars.m_Start_Date);
      barArray[i].final_Point = ((ts.Days + 1) * (100 * m_ValuePerPixel)) 
      	+ (ts.Hours * Convert.ToSingle(2.5 * m_ValuePerPixel));
      barArray[i].ID = Convert.ToInt32(rows[i]["Job_ID"]);
      barArray[i].Job_Transaction_ID = 
      	Convert.ToInt32(rows[i]["Job_Transaction_ID"]);
      barArray[i].Is_Final_Job_Status = false;

// Expected
if (Convert.ToInt32(rows[i]["Status_ID"]) == 2)
{
      barArray[i].color = Color.DarkBlue;
}

// In-Progress
if (Convert.ToInt32(rows[i]["Status_ID"]) == 3)
{
      barArray[i].color = Color.Black;
}

// Finished
if (Convert.ToInt32(rows[i]["Status_ID"]) == 5)
{
      barArray[i].color = Color.DimGray;
}

// Waste
if (Convert.ToInt32(rows[i]["Status_ID"]) == 6)
{
      barArray[i].color = Color.Red;
}

if (barArray[i].final_Point > 1)
      barArrayList.Add(barArray[i]);
}
#endregion

GenerateBars

Method consumes generated resultset and puts them in visual form by drawing them. The actual drawing take place here.

void GenerateBars(PaintEventArgs pevent)
{
      int generatedBarCount = 0;
      System.Drawing.Drawing2D.GraphicsPath path = new GraphicsPath();
      Pen drawingPen = new Pen(Color.Gray);
      Bar barStruct;
      Color shadeColor, fillColor;
      // defines magnitude of concern bar
      int bar = 0;
      Rectangle r = new Rectangle();

      while (generatedBarCount < barArrayList.Count) 
      {
            if (generatedBarCount >= barArrayList.Count)
                  goto Finish1;

            barStruct = (Bar)barArrayList[generatedBarCount];
            fillColor = barStruct.color;
            shadeColor = barStruct.color;
            bar = Convert.ToInt32(barStruct.final_Point) - 
			vert.ToInt32(barStruct.initial_Point);
            r = new Rectangle(0, 0, bar, 18);
            r.X = Convert.ToInt32(barStruct.initial_Point);
            r.Y += 4;
            i = i + bar;

            path = new GraphicsPath();
            path.AddRectangle(r);
            PathGradientBrush brush = new PathGradientBrush(path);
            brush.WrapMode = WrapMode.TileFlipX;
            brush.SurroundColors = new Color[] { shadeColor };
            brush.CenterColor = Color.White;

            //Draw the bar Background
            pevent.Graphics.FillPath(brush, path);

            //...and border
            pevent.Graphics.DrawPath(drawingPen, path);
            generatedBarCount++;
            brush.Dispose();
      }

      Finish1:
      drawingPen.Dispose();
      path.Dispose();
}

Bar_MouseMove

When mouse moves over a bar frame, this event method is called. On this method, mouse coordinates are extracted to find bar on which mouse is hovering if it is not on generated bar it will display information of bar context. When mouse is over generated bar then respective popup dialog will appear which contains information about the particular event, job or perpetual inventory, e.g. if mouse hover on event bar then popup will display that particular event information.

private void Bar_MouseMove(object sender, MouseEventArgs e)
{
      // bar array is not initialize 
      if (barArrayList == null)
            return;
	
      // balloon dialog is not allowed to be open on hover
      if (!Is_HoverEnable)
            return;

      System.Drawing.Point po = this.FindForm().PointToClient
			stem.Windows.Forms.Control.MousePosition);
      System.Drawing.Point po2 = this.PointToClient
			stem.Windows.Forms.Control.MousePosition);

      if (po.X == poLast.X && po.Y == poLast.Y)
            return;

      poLast = po;

      // base balloon dialog is not null then dispose it
      if (aForm != null)
            aForm.Dispose();

      float m_X = po2.X; 
      Bar barStruct;
            
      int DisplayShift = Convert.ToInt32(temp / m_ValuePerPixel * 0.5);

      #region Traversing current bar
      for (int i = 0; i < barArrayList.Count; i++)
      {
            barStruct = (Bar)barArrayList[i];

            // mouse is over generated bar
            if (m_X >= barStruct.initial_Point && m_X <= barStruct.final_Point)
            {
                  // Raw material balloon
                  if (perspective_ID == 0)
                  {
                        // Raw material non Event balloon dialog
                        if (!is_Event)
                        {
                              aForm = new GoodsBalloon(filter, 
					 barStruct.color, rows);
                        }
                        // Raw material Event balloon dialog
                        else
                        {
                              aForm = new ActivityBalloon(barStruct.ID);
                        }
                  }

                  // Job balloon dialog
                  if (perspective_ID == 1)
                  {
                        aForm = new JobBalloon(barStruct.ID, 
				truct.Job_Transaction_ID);
                  }

                  // Finished Goods balloon
                  if (perspective_ID == 2)
                  {	
                        // Finished Goods non Event balloon dialog
                        if (!is_Event)
                        {
                              aForm = new GoodsBalloon(filter, 
					 barStruct.color, rows);
                        }
                        // Finished Goods Event balloon dialog
                        else
                        {
                              aForm = new ActivityBalloon(barStruct.ID);
                        }
                  }

                  // Displaying selected balloon dialog 
                  aForm.setBalloonPosition(this.FindForm(), po);
                  aForm.Show();
                  this.Focus();
                  return;
      }
}
#endregion

// mouse is not on generated bar
string tag = "";
string name = "";

switch (perspective_ID)
{
      case 0:
      tag = "Raw Material";
      name = this.Parent.Controls.Find("Tag", true)[0].Text;
      break;

      case 1:
      tag = "Job ID";
      name = this.Parent.Controls.Find("Tag", true)[0].Text;
      break;

      case 2:
      tag = "Finished Goods";
      name = this.Parent.Controls.Find("Tag", true)[0].Text;
      break;
}

aForm = new VacantBalloon(tag, name);
aForm.setBalloonPosition(this.FindForm(), po);
aForm.Show();
this.Focus();
}

OnMouseClick

This event is called when status of job is needed to be changed. It can be called by clicking the concerned bar against which popup dialog will prompt for input.

protected override void OnMouseClick(MouseEventArgs e)
{
      float m_X = e.X;
      Bar barStruct;

      if (perspective_ID == 2 || perspective_ID == 1)
      {
            return;
      }

      for (int i = 0; i < barArrayList.Count; i++)
      {
            barStruct = (Bar)barArrayList[i];
            if (m_X >= barStruct.initial_Point && m_X <= barStruct.final_Point)
            {
                  # region
                  if (!Is_HoverEnable)
                        return;
                  if (aForm != null)
                        aForm.Dispose();
                  if (aFormConcreate != null)
                        aFormConcreate.Dispose();
                  System.Drawing.Point po = this.FindForm().PointToClient
                  	(System.Windows.Forms.Control.MousePosition);
                  System.Drawing.Point poi = po;

                  if (perspective_ID == 1 && barStruct.Is_Final_Job_Status)
                        Control.JobStatusBalloon.ShowBox(barStruct, poi);
                  #endregion
            }
      }
      base.OnMouseClick(e);
}

Bar_MouseLeave

Event is called when mouse leaves current bar frame, it will dispose of current popup dialog.

public void Bar_MouseLeave(object sender, EventArgs e)
{
      if (aForm != null)
            aForm.Dispose();
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here