I am getting an exception in the C1FlexGrid at a function that looks obfuscated but is called from inside C1.Win.C1FlexGrid.C1FlexGrid.GetMergedRange. We do a bunch of custom cell merging to get a nested table look and occasionally we get a NullReferenceException and a Red X across the control. I'm not sure what we are doing to trigger this since access to the control is only being done on the UI thread and we have locks placed around access to the control components. We are not doing any model binding so there should be no data changes that are triggering this error. Here is the stack trace I am seeing:
Object reference not set to an instance of an object.
Exception(NullReferenceException): Source="C1.Win.C1FlexGrid"; Target=null; Tag=null;
Message = "Object reference not set to an instance of an object."
Environment: WindowsIdentity="TPSLAB4\tpsadmin" ThreadIdentity="" DomainName="MobileCADClient.exe" DateTime=["2016-10-13 18:29:42.287"] OSVersion=["Microsoft Windows NT 6.2.9200.0"] MachineName="TPSWIN7-9" ThreadName=null UserName="tpsadmin"
ThreadId="5532"
Additional Information - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
UserID="dbostwick"
OfficerName=["dbostwick, "]
OfficerID=11269
Remaining Stack Trace - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
at C1.Win.C1FlexGrid.C1FlexGrid.a.b(Object A_0, Object A_1)
at C1.Win.C1FlexGrid.C1FlexGrid.GetMergedRange(Int32 row, Int32 col, Boolean clip)
at C1.Win.C1FlexGrid.C1FlexGrid.DrawCell(PaintEventArgs e, Int32 row, Int32 col)
at C1.Win.C1FlexGrid.C1FlexGrid.DrawRow(PaintEventArgs e, Int32 row)
at C1.Win.C1FlexGrid.C1FlexGridBase.a(PaintEventArgs A_0)
at C1.Win.C1FlexGrid.C1FlexGridBase.OnPaint(PaintEventArgs e)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at C1.Win.C1FlexGrid.Util.BaseControls.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
I have the code for the whole class that touches this form pasted below. If you could give any pointers I would really appreciate it.
namespace formNamespace
{
public class DispatchSuper : System.Windows.Forms.UserControl
{
#region Private Members
private object _lock = new object();
private System.Windows.Forms.Panel pnlMainSuperView;
private C1.Win.C1FlexGrid.C1FlexGrid grdCad;
private C1.Win.C1FlexGrid.C1FlexGrid grdUnits;
private System.Windows.Forms.Splitter splitMain;
private System.ComponentModel.IContainer components;
private System.Windows.Forms.ImageList imgCallViewImages;
private CallDisplaySettings _settings = null;
private MobileCalls _calls = null;
private QueuedUnits _qUnits = null;
private MobileActiveUnit _activeUnit = null;
private DispatchUnits _units = null;
private bool _allowUnitAssign = false;
private bool _allowCallQueuing = false;
private System.Windows.Forms.ContextMenuStrip mnuCallGridPopup;
private System.Windows.Forms.ContextMenuStrip mnuUnitsGridPopup;
private ToolStripMenuItem mnuCallGridPopupGetCallNotes;
private ToolStripMenuItem mnuUnitsGridPopupUnitInfo;
private ToolStripMenuItem mnuCallGridPopupAssign;
private ToolStripMenuItem mnuCallGridPopupQueue;
private ToolStripSeparator toolStripSeparator1;
private ToolStripSeparator toolStripSeparator2;
private ToolStripMenuItem mnuCallGridPopupCancel;
private ToolStripSeparator toolStripSeparator3;
private ToolStripMenuItem mnuUnitsGridPopupCancel;
#endregion
#region Events and Delegates
/// <summary>
/// EVENT HANDLER: Event handler for popup context menus. Has standard EventHandler
/// arguments and an additional commandArgument string value.
/// </summary>
public delegate void PopupEventHandler(object sender, DispatchSuperEventArgs e);
/// <summary>
/// EVENT: Raised when grdCad is clicked.
/// </summary>
[Browsable(true), Description("Event raised when the Call grid is clicked.")]
public event PopupEventHandler CallGridPopupContextMenu;
/// <summary>
/// EVENT: Raised when grdUnits is clicked.
/// </summary>
[Browsable(true), Description("Event raised when the Units grid is clicked.")]
public event PopupEventHandler UnitsGridPopupContextMenu;
#endregion
#region Property Overrides
public override Color BackColor
{
get
{
lock (_lock)
{
return base.BackColor;
}
}
set
{
lock (_lock)
{
base.BackColor = value;
mnuCallGridPopup.BackColor = value;
foreach (ToolStripItem menuItem in mnuCallGridPopup.Items)
{
menuItem.BackColor = value;
}
mnuUnitsGridPopup.BackColor = value;
}
}
}
public override Color ForeColor
{
get
{
lock (_lock)
{
return base.ForeColor;
}
}
set
{
lock (_lock)
{
base.ForeColor = value;
mnuCallGridPopup.ForeColor = value;
foreach (ToolStripItem menuItem in mnuCallGridPopup.Items)
{
menuItem.ForeColor = value;
}
mnuUnitsGridPopup.ForeColor = value;
}
}
}
public override Font Font
{
get
{
lock (_lock)
{
return base.Font;
}
}
set
{
lock (_lock)
{
base.Font = value;
mnuCallGridPopup.Font = new Font(mnuCallGridPopup.Font.FontFamily, value.Size);
mnuUnitsGridPopup.Font = new Font(mnuUnitsGridPopup.Font.FontFamily, value.Size);
}
}
}
#endregion
#region Constructor
/// <summary>
/// CONSTRUCTOR: Default constructor
/// </summary>
public DispatchSuper()
{
InitializeComponent();
InitializeGrids();
_settings = new CallDisplaySettings();
}
#endregion
#region Dispose
protected override void Dispose(bool disposing)
{
if (!IsDisposed)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
}
#endregion
#region InitializeGrids
/// <summary>
/// Init super view grids
/// </summary>
private void InitializeGrids()
{
//init the call grid
this.grdCad.Rows.Count = 0;
C1.Win.C1FlexGrid.Row r = this.grdCad.Rows.Add();
r.AllowMerging = true;
C1.Win.C1FlexGrid.CellRange rng = this.grdCad.GetCellRange(r.Index,
CadSupervisorGridCols.Quick_Call_Num, r.Index,
CadSupervisorGridCols.Call_Sheet_Number_Blank);
if(this.NightMode)
rng.Style = this.grdCad.Styles["CallHeaderDark"];
else
rng.Style = this.grdCad.Styles["CallHeader"];
r[CadSupervisorGridCols.Quick_Call_Num] = "Call #";
r[CadSupervisorGridCols.Call_To_Address] = "Call To Address";
r[CadSupervisorGridCols.Dispatch_Unit] = "Call To Address";
r[CadSupervisorGridCols.Dispatch_Unit_Blank] = "Call To Address";
r[CadSupervisorGridCols.Dispatch_Assign] = "Call To Address";
r[CadSupervisorGridCols.Dispatch_Enroute] = "Call To Address";
r[CadSupervisorGridCols.Dispatch_Arrive] = "Call To Address";
r[CadSupervisorGridCols.Call_Type] = "Call Type";
r[CadSupervisorGridCols.Call_Type_Blank] = "Call Type";
r[CadSupervisorGridCols.Call_Priority] = "Priority";
r[CadSupervisorGridCols.Call_Time] = "Call Time";
r[CadSupervisorGridCols.Call_Sheet_Number] = "Call Sheet #";
r[CadSupervisorGridCols.Call_Sheet_Number_Blank] = "Call Sheet #";
//hide some cols
for(int index = 13 ; index <= 20 ; index++)
this.grdCad.Cols[index].Width = 0;
//init the units grid
this.grdUnits.Rows.Count = 0;
C1.Win.C1FlexGrid.Row rUnits = this.grdUnits.Rows.Add();
rUnits.AllowMerging = true;
C1.Win.C1FlexGrid.CellRange rngUnits = this.grdUnits.GetCellRange(rUnits.Index,
0, rUnits.Index, 2);
if(this.NightMode)
rngUnits.Style = this.grdUnits.Styles["UnitHeaderDark"];
else
rngUnits.Style = this.grdUnits.Styles["UnitHeader"];
rUnits[0] = "Unit #";
rUnits[1] = "Description";
rUnits[2] = "Description";
//hide some cols
for(int index = 3 ; index <= 6 ; index++)
this.grdUnits.Cols[index].Width = 0;
}
#endregion
#region grdCad_Resize
/// <summary>
/// Handle resize of the dispatch (cad) grid, resizes all cols as
/// splitter is moved.
/// </summary>
/// <param name="sender">Grid</param>
/// <param name="e">EventArgs</param>
private void grdCad_Resize(object sender, System.EventArgs e)
{
try
{
this.grdCad.Redraw = false;
int colw = (this.grdCad.Width - 60) / 12;
foreach(C1.Win.C1FlexGrid.Column c in this.grdCad.Cols)
{
if(c.Index != 0 && c.Index < 13)
c.WidthDisplay = colw;
}
}
catch(Exception _ex)
{
Ems.HandleException(this, _ex, Ems.AsParams(sender, e));
}
finally
{
this.grdCad.Redraw = true;
}
}
#endregion
#region NightMode
private bool _NightMode = false;
/// <summary>
/// Enables of disables night mode for this control
/// </summary>
[Browsable(true), Description("Controls night mode for this view.")]
public bool NightMode
{
get
{
lock (_lock)
{
return _NightMode;
}
}
set
{
lock (_lock)
{
_NightMode = value;
}
}
}
private Color _color = Color.Red;
/// <summary>
/// Gets, Sets night mode color
/// </summary>
public Color NightModeColor
{
get
{
lock (_lock)
{
return _color;
}
}
set
{
lock (_lock)
{
_color = value;
}
}
}
#endregion
#region SplitLocation
private int _UnitGridWidth;
/// <summary>
/// GET, SET: Location of the splitter
/// </summary>
[Browsable(false)]
public int SplitLocation
{
get
{
lock (_lock)
{
return _UnitGridWidth;
}
}
set
{
lock (_lock)
{
_UnitGridWidth = value;
}
}
}
#endregion
#region LoadView
/// <summary>
/// Handles loading call and unit data into grids
/// </summary>
private void LoadView()
{
try
{
//suspend grid drawing, eliminates grid flickering
grdCad.Redraw = false;
grdUnits.Redraw = false;
//add calls to grid
this.grdCad.Rows.Count = 1;
//create a dummy call to display NO ACTIVE CALLS in grid
if (_calls.Count == 0)
{
this.AddLine(new MobileCall());
}
else
{
foreach (DictionaryEntry dCall in _calls.Cast<DictionaryEntry>().ToList())
{
MobileCall c = (MobileCall) dCall.Value;
this.AddLine(c);
foreach (DictionaryEntry dUnit in c.Units)
{
MobileUnit u = (MobileUnit) dUnit.Value;
if (u.AssignTime != null) // Ignore queued units (not assinged)
{
this.AddLine(u, c);
}
}
if (_qUnits != null)
{
foreach (QueuedUnit qu in _qUnits.ToList())
{
if (c.RecordNumber == qu.CallRecordNumber)
{
this.AddLine(qu, c);
}
}
}
}
}
//add dispatch units to grid
this.grdUnits.Rows.Count = 1;
bool Found = false;
foreach (DictionaryEntry de in _units.Cast<DictionaryEntry>().ToList())
{
DispatchUnit u = (DispatchUnit) de.Value;
if (!_settings.AllUnits)
{
Found = false;
for (int Index = 0; Index < this._settings.SelectedUnitAgencies.Count; Index++)
{
string SelectedUnitAgency = this._settings.SelectedUnitAgencies[Index].ToString();
string UnitAgency = u.AgencyDescription;
if (SelectedUnitAgency == UnitAgency)
{
Found = true;
break;
}
}
if (!Found)
{
continue; // Don't add this unit to the grid.
}
Found = false;
for (int Index = 0; Index < this._settings.SelectedUnitTypes.Count; Index++)
{
string SelectedUnitType = this._settings.SelectedUnitTypes[Index].ToString();
string UnitType = u.TypeDescription;
if (SelectedUnitType == UnitType)
{
Found = true;
break;
}
}
if (!Found)
{
continue; // Don't add this unit to the grid.
}
Found = false;
if (u.TypeDescription == u.TypeSubTypeDescription)
{
Found = true;
}
else
{
for (int Index = 0; Index < this._settings.SelectedUnitSubTypes.Count; Index++)
{
string SelectedUnitSubType = this._settings.SelectedUnitSubTypes[Index].ToString();
string UnitSubType = u.TypeSubTypeDescription;
if (SelectedUnitSubType == UnitSubType)
{
Found = true;
break;
}
}
}
if (!Found)
{
continue; // Don't add this unit to the grid.
}
Found = false;
for (int Index = 0; Index < this._settings.SelectedUnitStatus.Count; Index++)
{
string SelectedUnitStatus = this._settings.SelectedUnitStatus[Index].ToString();
switch (SelectedUnitStatus)
{
case "Available":
if (false == u.IsDispatched &&
false == u.IsUnitEnroute &&
false == u.IsUnitArrived &&
null == u.OutOfVehicleLocation)
{
Found = true;
}
break;
case "Assigned":
if (u.IsDispatched)
{
Found = true;
}
break;
case "Enroute":
if (u.IsUnitEnroute)
{
Found = true;
}
break;
case "Arrived":
if (u.IsUnitArrived)
{
Found = true;
}
break;
case "Break":
if (null != u.OutOfVehicleLocation)
{
Found = true;
}
break;
}
if (Found)
{
break;
}
}
if (!Found)
{
continue; // Don't add this unit to the grid.
}
}
this.AddLine(u);
}
ReSortGrids(this._settings);
}
catch (Exception ex)
{
Ems.HandleException(this, ex, Ems.AsParams(_calls, _units));
}
finally
{
grdCad.Redraw = true;
grdUnits.Redraw = true;
}
}
#endregion
#region UpdateView
/// <summary>
/// Updates the cad supervisor view, with new data
/// </summary>
/// <param name="calls"></param>
/// <param name="units"></param>
/// <param name="qUnits"></param>
/// <param name="activeUnit"></param>
/// <param name="settings"></param>
public void UpdateView(MobileCalls calls, DispatchUnits units, QueuedUnits qUnits, MobileActiveUnit activeUnit, CallDisplaySettings settings)
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)(() => this.UpdateView(calls, units, qUnits, activeUnit, settings)));
return;
}
lock (_lock)
{
// TEMP: Trying to track down TPS-24492
#region Trying to track down TPS-24492
// This section is temporary but it will stay here until we know a client no longer sees the Red X in the Calls View.
// If you see this code and no one has reported the Red X in 2016.4 after 1-2 months on the software (see TPS-24492
// affected clients list), go ahead and remove this region.
if (calls == null) throw new ArgumentNullException(nameof(calls));
if (units == null) throw new ArgumentNullException(nameof(units));
if (qUnits == null) throw new ArgumentNullException(nameof(qUnits));
if (activeUnit == null) throw new ArgumentNullException(nameof(activeUnit));
if (settings == null) throw new ArgumentNullException(nameof(settings));
#endregion
if (IsDisposed || Disposing)
{
// If control is disposed already ignore call
return;
}
// Deep copy these collections so we don't have to worry about them changing while we are drawing.
_calls = calls;
_units = units;
_qUnits = qUnits;
_activeUnit = activeUnit;
_settings = settings;
LoadView();
}
}
/// <summary>
/// Updates the cad supervisor view, with existing data.
/// </summary>
public void UpdateView()
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)(this.UpdateView));
return;
}
lock (_lock)
{
if (IsDisposed || Disposing)
{
// If control is disposed already ignore call
return;
}
LoadView();
}
}
#endregion
#region Component 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.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DispatchSuper));
this.pnlMainSuperView = new System.Windows.Forms.Panel();
this.grdUnits = new C1.Win.C1FlexGrid.C1FlexGrid();
this.splitMain = new System.Windows.Forms.Splitter();
this.grdCad = new C1.Win.C1FlexGrid.C1FlexGrid();
this.mnuCallGridPopup = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mnuCallGridPopupGetCallNotes = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuCallGridPopupAssign = new System.Windows.Forms.ToolStripMenuItem();
this.mnuCallGridPopupQueue = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.mnuCallGridPopupCancel = new System.Windows.Forms.ToolStripMenuItem();
this.imgCallViewImages = new System.Windows.Forms.ImageList(this.components);
this.mnuUnitsGridPopup = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mnuUnitsGridPopupUnitInfo = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.mnuUnitsGridPopupCancel = new System.Windows.Forms.ToolStripMenuItem();
this.pnlMainSuperView.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.grdUnits)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.grdCad)).BeginInit();
this.mnuCallGridPopup.SuspendLayout();
this.mnuUnitsGridPopup.SuspendLayout();
this.SuspendLayout();
//
// pnlMainSuperView
//
this.pnlMainSuperView.Controls.Add(this.grdUnits);
this.pnlMainSuperView.Controls.Add(this.splitMain);
this.pnlMainSuperView.Controls.Add(this.grdCad);
this.pnlMainSuperView.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlMainSuperView.Location = new System.Drawing.Point(0, 0);
this.pnlMainSuperView.Name = "pnlMainSuperView";
this.pnlMainSuperView.Size = new System.Drawing.Size(808, 512);
this.pnlMainSuperView.TabIndex = 0;
//
// grdUnits
//
this.grdUnits.AllowEditing = false;
this.grdUnits.AllowMerging = C1.Win.C1FlexGrid.AllowMergingEnum.RestrictCols;
this.grdUnits.AllowResizing = C1.Win.C1FlexGrid.AllowResizingEnum.None;
this.grdUnits.AllowSorting = C1.Win.C1FlexGrid.AllowSortingEnum.None;
this.grdUnits.ColumnInfo = "7,0,0,0,0,85,Columns:0{Width:79;}\t1{Width:69;}\t3{Width:90;Name:\"Agency\";}\t4{Name:" +
"\"UnitType\";}\t5{Name:\"Aval\";}\t6{Name:\"UnitNo\";}\t";
this.grdUnits.Dock = System.Windows.Forms.DockStyle.Fill;
this.grdUnits.DrawMode = C1.Win.C1FlexGrid.DrawModeEnum.OwnerDraw;
this.grdUnits.HighLight = C1.Win.C1FlexGrid.HighLightEnum.Never;
this.grdUnits.Location = new System.Drawing.Point(629, 0);
this.grdUnits.Name = "grdUnits";
this.grdUnits.Rows.Count = 2;
this.grdUnits.Rows.DefaultSize = 17;
this.grdUnits.Size = new System.Drawing.Size(179, 512);
this.grdUnits.StyleInfo = resources.GetString("grdUnits.StyleInfo");
this.grdUnits.TabIndex = 10;
this.grdUnits.MouseUp += new System.Windows.Forms.MouseEventHandler(this.grdUnits_MouseUp);
//
// splitMain
//
this.splitMain.Location = new System.Drawing.Point(624, 0);
this.splitMain.Name = "splitMain";
this.splitMain.Size = new System.Drawing.Size(5, 512);
this.splitMain.TabIndex = 9;
this.splitMain.TabStop = false;
this.splitMain.SplitterMoved += new System.Windows.Forms.SplitterEventHandler(this.splitMain_SplitterMoved);
//
// grdCad
//
this.grdCad.AllowEditing = false;
this.grdCad.AllowMerging = C1.Win.C1FlexGrid.AllowMergingEnum.RestrictCols;
this.grdCad.AllowResizing = C1.Win.C1FlexGrid.AllowResizingEnum.None;
this.grdCad.ColumnInfo = resources.GetString("grdCad.ColumnInfo");
this.grdCad.Dock = System.Windows.Forms.DockStyle.Left;
this.grdCad.DrawMode = C1.Win.C1FlexGrid.DrawModeEnum.OwnerDraw;
this.grdCad.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.grdCad.ForeColor = System.Drawing.SystemColors.ControlText;
this.grdCad.HighLight = C1.Win.C1FlexGrid.HighLightEnum.Never;
this.grdCad.Location = new System.Drawing.Point(0, 0);
this.grdCad.Name = "grdCad";
this.grdCad.Rows.Count = 2;
this.grdCad.Rows.DefaultSize = 17;
this.grdCad.Size = new System.Drawing.Size(624, 512);
this.grdCad.StyleInfo = resources.GetString("grdCad.StyleInfo");
this.grdCad.TabIndex = 8;
this.grdCad.TabStop = false;
this.grdCad.MouseUp += new System.Windows.Forms.MouseEventHandler(this.grdCad_MouseUp);
this.grdCad.Resize += new System.EventHandler(this.grdCad_Resize);
//
// mnuCallGridPopup
//
this.mnuCallGridPopup.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.mnuCallGridPopup.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuCallGridPopupGetCallNotes,
this.toolStripSeparator1,
this.mnuCallGridPopupAssign,
this.mnuCallGridPopupQueue,
this.toolStripSeparator2,
this.mnuCallGridPopupCancel});
this.mnuCallGridPopup.Name = "mnuCallGridPopup";
this.mnuCallGridPopup.Size = new System.Drawing.Size(172, 104);
this.mnuCallGridPopup.Opening += new System.ComponentModel.CancelEventHandler(this.mnuCallGridPopup_Opening);
//
// mnuCallGridPopupGetCallNotes
//
this.mnuCallGridPopupGetCallNotes.Name = "mnuCallGridPopupGetCallNotes";
this.mnuCallGridPopupGetCallNotes.Size = new System.Drawing.Size(171, 22);
this.mnuCallGridPopupGetCallNotes.Text = "Get Call Notes";
this.mnuCallGridPopupGetCallNotes.Click += new System.EventHandler(this.CallGridPopup);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(168, 6);
//
// mnuCallGridPopupAssign
//
this.mnuCallGridPopupAssign.Name = "mnuCallGridPopupAssign";
this.mnuCallGridPopupAssign.Size = new System.Drawing.Size(171, 22);
this.mnuCallGridPopupAssign.Text = "Assign to This Call";
this.mnuCallGridPopupAssign.Click += new System.EventHandler(this.CallGridPopup);
//
// mnuCallGridPopupQueue
//
this.mnuCallGridPopupQueue.BackColor = System.Drawing.SystemColors.Control;
this.mnuCallGridPopupQueue.Name = "mnuCallGridPopupQueue";
this.mnuCallGridPopupQueue.Size = new System.Drawing.Size(171, 22);
this.mnuCallGridPopupQueue.Text = "Queue to This Call";
this.mnuCallGridPopupQueue.Click += new System.EventHandler(this.CallGridPopup);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(168, 6);
//
// mnuCallGridPopupCancel
//
this.mnuCallGridPopupCancel.Name = "mnuCallGridPopupCancel";
this.mnuCallGridPopupCancel.Size = new System.Drawing.Size(171, 22);
this.mnuCallGridPopupCancel.Text = "Cancel";
//
// imgCallViewImages
//
this.imgCallViewImages.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgCallViewImages.ImageStream")));
this.imgCallViewImages.TransparentColor = System.Drawing.Color.Transparent;
this.imgCallViewImages.Images.SetKeyName(0, "EMS");
this.imgCallViewImages.Images.SetKeyName(1, "FIRE");
this.imgCallViewImages.Images.SetKeyName(2, "PD");
this.imgCallViewImages.Images.SetKeyName(3, "SHF");
//
// mnuUnitsGridPopup
//
this.mnuUnitsGridPopup.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuUnitsGridPopupUnitInfo,
this.toolStripSeparator3,
this.mnuUnitsGridPopupCancel});
this.mnuUnitsGridPopup.Name = "mnuUnitsGridPopup";
this.mnuUnitsGridPopup.Size = new System.Drawing.Size(117, 54);
this.mnuUnitsGridPopup.Text = "Unit Info";
//
// mnuUnitsGridPopupUnitInfo
//
this.mnuUnitsGridPopupUnitInfo.Name = "mnuUnitsGridPopupUnitInfo";
this.mnuUnitsGridPopupUnitInfo.Size = new System.Drawing.Size(116, 22);
this.mnuUnitsGridPopupUnitInfo.Text = "Unit Info";
this.mnuUnitsGridPopupUnitInfo.Click += new System.EventHandler(this.UnitsGridPopup);
//
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
this.toolStripSeparator3.Size = new System.Drawing.Size(113, 6);
//
// mnuUnitsGridPopupCancel
//
this.mnuUnitsGridPopupCancel.Name = "mnuUnitsGridPopupCancel";
this.mnuUnitsGridPopupCancel.Size = new System.Drawing.Size(116, 22);
this.mnuUnitsGridPopupCancel.Text = "Cancel";
//
// DispatchSuper
//
this.Controls.Add(this.pnlMainSuperView);
this.Name = "DispatchSuper";
this.Size = new System.Drawing.Size(808, 512);
this.Resize += new System.EventHandler(this.DispatchSuper_Resize);
this.pnlMainSuperView.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.grdUnits)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.grdCad)).EndInit();
this.mnuCallGridPopup.ResumeLayout(false);
this.mnuUnitsGridPopup.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
#region DispatchSuper_Resize
/// <summary>
/// EVENT HANDLER: Handles the main panel resize event, so we can
/// maintain a constant active unit grid width when the window resizes.
/// </summary>
/// <param name="sender">Panel</param>
/// <param name="e">EventArgs</param>
private void DispatchSuper_Resize(object sender, System.EventArgs e)
{
grdCad.Redraw = false;
grdUnits.Redraw = false;
grdCad.Width = pnlMainSuperView.Width - _UnitGridWidth;
grdCad.Redraw = true;
grdUnits.Redraw = true;
}
#endregion
#region splitMain_SplitterMoved
/// <summary>
/// EVENT HANDLER: Stores the new active units grid width for when we
/// resize the window.
/// </summary>
/// <param name="sender">Split Control</param>
/// <param name="e">SplitterEventArgs</param>
private void splitMain_SplitterMoved(object sender, System.Windows.Forms.SplitterEventArgs e)
{
_UnitGridWidth = grdUnits.Width + splitMain.Width;
}
#endregion
#region AddLine Call
/// <summary>
/// Adds call information to dispatch
/// grid
/// </summary>
/// <param name="Call">MobileCall</param>
private void AddLine(MobileCall Call)
{
try
{
CellRange rngQckRefNum;
C1.Win.C1FlexGrid.Row rHeader = this.grdCad.Rows[0];
C1.Win.C1FlexGrid.CellRange rngHeader = this.grdCad.GetCellRange(rHeader.Index,
0, rHeader.Index, 11);
C1.Win.C1FlexGrid.Row r = this.grdCad.Rows.Add();
r.AllowMerging = true;
if(this.NightMode)
{
rngHeader.Style = this.grdCad.Styles["CallHeaderDark"];
rngHeader.Style.ForeColor = this.NightModeColor;
this.grdCad.Styles["EmptyArea"].BackColor = Color.Black;
}
else
{
rngHeader.Style = this.grdCad.Styles["CallHeader"];
this.grdCad.Styles["EmptyArea"].BackColor = SystemColors.Control;
this.grdCad.BackColor = SystemColors.Window;
}
if(Call.RecordNumber == 0)
{
r[CadSupervisorGridCols.Quick_Call_Num] = " ";
r[CadSupervisorGridCols.Call_To_Address] = "NO ACTIVE CALLS";
r[CadSupervisorGridCols.Dispatch_Unit] = "NO ACTIVE CALLS";
r[CadSupervisorGridCols.Dispatch_Unit_Blank] = "NO ACTIVE CALLS";
r[CadSupervisorGridCols.Dispatch_Assign] = "NO ACTIVE CALLS";
r[CadSupervisorGridCols.Dispatch_Enroute] = "NO ACTIVE CALLS";
r[CadSupervisorGridCols.Dispatch_Arrive] = "NO ACTIVE CALLS";
r[CadSupervisorGridCols.Call_Type] = "NO ACTIVE CALLS";
r[CadSupervisorGridCols.Call_Type_Blank] = "NO ACTIVE CALLS";
r[CadSupervisorGridCols.Call_Priority] = "NO ACTIVE CALLS";
r[CadSupervisorGridCols.Call_Time] = "NO ACTIVE CALLS";
r[CadSupervisorGridCols.Call_Sheet_Number] = "NO ACTIVE CALLS";
r[CadSupervisorGridCols.Call_Sheet_Number_Blank] = "NO ACTIVE CALLS";
}
else
{
//Create the call line and apply style MobileCallLine
r[CadSupervisorGridCols.Quick_Call_Num] = Call.QuickCallRefrenceNumber;
r[CadSupervisorGridCols.Call_To_Address] = Call.LocationString;
r[CadSupervisorGridCols.Dispatch_Unit] = Call.LocationString;
r[CadSupervisorGridCols.Dispatch_Unit_Blank] = Call.LocationString;
r[CadSupervisorGridCols.Dispatch_Assign] = Call.LocationString;
r[CadSupervisorGridCols.Dispatch_Enroute] = Call.LocationString;
r[CadSupervisorGridCols.Dispatch_Arrive] = Call.LocationString;
r[CadSupervisorGridCols.Call_Type] = Call.CallTypeDescription;
r[CadSupervisorGridCols.Call_Type_Blank] = Call.CallTypeDescription;
r[CadSupervisorGridCols.Call_Priority] = Call.CallPriorityDescription;
r[CadSupervisorGridCols.Call_Time] = Call.CallReceivedTime;
r[CadSupervisorGridCols.Call_Sheet_Number] = Call.CallSheetID;
r[CadSupervisorGridCols.Call_Sheet_Number_Blank] = Call.CallSheetID;
//Call sorting items
r["RECNO"] = Call.RecordNumber;
r["RECNO1"] = Call.RecordNumber;
r["RECNO2"] = Call.RecordNumber;
r["RECNO3"] = Call.RecordNumber;
r["CALLTIME"] = Call.CallReceivedTime;
r["PRIORITY"] = Call.CallPriorityDescription;
r["CALLTYPE"] = Call.CallTypeDescription;
r["NOTDISPATCHED"] = Call.Units.Count == 0 ? 0 : 1;
r.UserData = Call;
}
C1.Win.C1FlexGrid.CellRange rng = this.grdCad.GetCellRange(r.Index,
CadSupervisorGridCols.Call_To_Address, r.Index,
CadSupervisorGridCols.Call_Sheet_Number_Blank);
rngQckRefNum = this.grdCad.GetCellRange(r.Index, CadSupervisorGridCols.Quick_Call_Num);
if(this.NightMode)
{
rng.Style = this.grdCad.Styles["MobileCallLineDark"];
rng.Style.ForeColor = this.NightModeColor;
//call quick ref num cell
if(Call.Units.Count == 0 && Call.RecordNumber != 0)
rngQckRefNum.Style = this.grdCad.Styles["QuickRefNumNotAssignedDark"];
else if(Call.RecordNumber == 0)
rngQckRefNum.Style = this.grdCad.Styles["MobileCallLineDark"];
//Call suspend
if(Call.CallSuspendFlag == "Y")
rngQckRefNum.Style = this.grdCad.Styles["CallSuspendDark"];
}
else
{
rng.Style = this.grdCad.Styles["MobileCallLine"];
//call quick ref num cell
if(Call.Units.Count == 0 && Call.RecordNumber != 0)
rngQckRefNum.Style = this.grdCad.Styles["QuickRefNumNotAssigned"];
else if(Call.RecordNumber == 0)
rngQckRefNum.Style = this.grdCad.Styles["MobileCallLine"];
//call suspend
if(Call.CallSuspendFlag == "Y")
rngQckRefNum.Style = this.grdCad.Styles["CallSuspend"];
}
//create the unit info title row and apply style UnitInfoHeader
r = this.grdCad.Rows.Add();
if(Call.RecordNumber == 0)
r[CadSupervisorGridCols.Quick_Call_Num] = " ";
else
r[CadSupervisorGridCols.Quick_Call_Num] = Call.QuickCallRefrenceNumber;
r[CadSupervisorGridCols.Unit_Type_Icon] = "Type";
r[CadSupervisorGridCols.Dispatch_Unit] = "Unit";
r[CadSupervisorGridCols.Dispatch_Unit_Blank] = "Unit";
r[CadSupervisorGridCols.Dispatch_Assign] = "Assign";
r[CadSupervisorGridCols.Dispatch_Enroute] = "Enroute";
r[CadSupervisorGridCols.Dispatch_Arrive] = "Arrive";
r[CadSupervisorGridCols.Dispatch_Trans_Start] = "Trans. Start";
r[CadSupervisorGridCols.Dispatch_Trans_End] = "Trans. End";
r[CadSupervisorGridCols.Dispatch_To_Station] = "To Station";
r[CadSupervisorGridCols.Dispatch_At_Station] = "At Station";
r[CadSupervisorGridCols.Call_Sheet_Number] = "Case Number";
r[CadSupervisorGridCols.Call_Sheet_Number_Blank] = "Case Number";
//Call Sorting
r["RECNO"] = Call.RecordNumber;
r["RECNO1"] = Call.RecordNumber;
r["RECNO2"] = Call.RecordNumber;
r["RECNO3"] = Call.RecordNumber;
r["CALLTIME"] = Call.CallReceivedTime;
r["PRIORITY"] = Call.CallPriorityDescription;
r["CALLTYPE"] = Call.CallTypeDescription;
r["NOTDISPATCHED"] = Call.Units.Count == 0 ? 0 : 1;
rng = this.grdCad.GetCellRange(r.Index,
CadSupervisorGridCols.Unit_Type_Icon, r.Index,
CadSupervisorGridCols.Call_Sheet_Number_Blank);
if(this.NightMode)
{
rng.Style = this.grdCad.Styles["UnitInfoHeaderDark"];
rng.Style.ForeColor = this.NightModeColor;
}
else
{
rng.Style = this.grdCad.Styles["UnitInfoHeader"];
}
r.AllowMerging = true;
}
catch(Exception _ex)
{
Ems.HandleException(this, _ex, Ems.AsParams(Call));
}
}
#endregion
#region AddLine QueuedUnit
/// <summary>
/// Adds a queued unit to a call
/// </summary>
/// <param name="qUnit">QueuedUnit, the unit to add.</param>
private void AddLine(QueuedUnit qUnit, MobileCall Call)
{
try
{
C1.Win.C1FlexGrid.Row r = this.grdCad.Rows.Add();
int imageIndex;
string unitTitle = string.Format("Unit: {0} Queued for call. ({1})", qUnit.UnitNumber, qUnit.QueueOrder);
r[CadSupervisorGridCols.Quick_Call_Num] = Call.QuickCallRefrenceNumber;
r[CadSupervisorGridCols.Unit_Type_Icon] = qUnit.UnitNumber;
r[CadSupervisorGridCols.Dispatch_Unit] = unitTitle;
r[CadSupervisorGridCols.Dispatch_Unit_Blank] = unitTitle;
r[CadSupervisorGridCols.Dispatch_Assign] = unitTitle;
r[CadSupervisorGridCols.Dispatch_Enroute] = unitTitle;
r[CadSupervisorGridCols.Dispatch_Arrive] = unitTitle;
r[CadSupervisorGridCols.Dispatch_Trans_Start] = unitTitle;
r[CadSupervisorGridCols.Dispatch_Trans_End] = unitTitle;
r[CadSupervisorGridCols.Dispatch_To_Station] = unitTitle;
r[CadSupervisorGridCols.Dispatch_At_Station] = unitTitle;
r[CadSupervisorGridCols.Call_Sheet_Number] = unitTitle;
r[CadSupervisorGridCols.Call_Sheet_Number_Blank] = unitTitle;
//Call sorting info
r["RECNO"] = qUnit.CallRecordNumber;
r["RECNO1"] = qUnit.CallRecordNumber;
r["RECNO2"] = qUnit.CallRecordNumber;
r["RECNO3"] = qUnit.CallRecordNumber;
r["CALLTIME"] = Call.CallReceivedTime;
r["PRIORITY"] = Call.CallPriorityDescription;
r["CALLTYPE"] = Call.CallTypeDescription;
r["NOTDISPATCHED"] = Call.Units.Count == 0 ? 0 : 1;
r.UserData = Call;
//add unit type images
if(qUnit.UnitTypeAbbreviation == "PD")
imageIndex = 2;
else if(qUnit.UnitTypeAbbreviation == "EMS")
imageIndex = 0;
else if(qUnit.UnitTypeAbbreviation == "FIRE")
imageIndex = 1;
else if(qUnit.UnitTypeAbbreviation == "SHF")
imageIndex = 3;
else
imageIndex = 2;
this.grdCad.SetCellImage(r.Index, CadSupervisorGridCols.Unit_Type_Icon, this.imgCallViewImages.Images[imageIndex]);
//format the unit icon cell
C1.Win.C1FlexGrid.CellRange rng = this.grdCad.GetCellRange(r.Index,
CadSupervisorGridCols.Unit_Type_Icon, r.Index,
CadSupervisorGridCols.Unit_Type_Icon);
if(this.NightMode)
{
rng.Style = this.grdCad.Styles["UnitIconFormatDark"];
rng.Style.ForeColor = this.NightModeColor;
}
else
{
rng.Style = this.grdCad.Styles["UnitIconFormat"];
}
//color the queued unit text red and bold it, this info is located in the style
//UnitChangeLocationText. Using the UnitChangeLocationText text style here since it
//has the same formatting characteristics we want.
C1.Win.C1FlexGrid.CellRange rngLocationText = this.grdCad.GetCellRange(r.Index,
CadSupervisorGridCols.Dispatch_Unit, r.Index,
CadSupervisorGridCols.Call_Type_Blank);
rngLocationText.Style = this.grdCad.Styles["UnitChangeLocationText"];
//merge the cells
r.AllowMerging = true;
this.grdCad.Cols[CadSupervisorGridCols.Unit_Type_Icon].AllowMerging = true;
}
catch(Exception ex)
{
Ems.HandleException(this, ex, Ems.AsParams(qUnit));
}
}
#endregion
#region AddLine Unit
/// <summary>
/// Adds unit data to a call in the dispatch
/// grid
/// </summary>
/// <param name="Unit">MobileUnit</param>
private void AddLine(MobileUnit Unit, MobileCall Call)
{
try
{
C1.Win.C1FlexGrid.Row r = this.grdCad.Rows.Add();
int imageIndex;
string UnitTitle = Unit.UnitNumber + " (" + Unit.NumberOfOfficersInUnit.ToString() + ")";
if(Unit.PrimaryUnit == "Y")
UnitTitle += " **";
//r[CadSupervisorGridCols.Unit_Type_Icon] = "";
r[CadSupervisorGridCols.Quick_Call_Num] = Unit.Parent.QuickCallRefrenceNumber;
r[CadSupervisorGridCols.Unit_Type_Icon] = Unit.UnitNumber;
r[CadSupervisorGridCols.Dispatch_Unit] = UnitTitle;
r[CadSupervisorGridCols.Dispatch_Unit_Blank] = UnitTitle;
//spaces added to prevent col merging when times are same
r[CadSupervisorGridCols.Dispatch_Assign] = AbbreviateTime(Unit.AssignTime);
r[CadSupervisorGridCols.Dispatch_Enroute] = AbbreviateTime(Unit.EnrouteTime) + " ";
r[CadSupervisorGridCols.Dispatch_Arrive] = AbbreviateTime(Unit.ArriveTime) + " ";
r[CadSupervisorGridCols.Dispatch_Trans_Start] = AbbreviateTime(Unit.TransStartTime) + " ";
r[CadSupervisorGridCols.Dispatch_Trans_End] = AbbreviateTime(Unit.TransEndTime) + " ";
r[CadSupervisorGridCols.Dispatch_To_Station] = AbbreviateTime(Unit.ToStationTime) + " ";
r[CadSupervisorGridCols.Dispatch_At_Station] = AbbreviateTime(Unit.AtStationTime) + " ";
//Call sorting info
r["RECNO"] = Unit.Parent.RecordNumber;
r["RECNO1"] = Unit.Parent.RecordNumber;
r["RECNO2"] = Unit.Parent.RecordNumber;
r["RECNO3"] = Unit.Parent.RecordNumber;
r["CALLTIME"] = Unit.Parent.CallReceivedTime;
r["PRIORITY"] = Unit.Parent.CallPriorityDescription;
r["CALLTYPE"] = Unit.Parent.CallTypeDescription;
r["NOTDISPATCHED"] = Unit.Parent.Units.Count == 0 ? 0 : 1;
if(Unit.CaseNumber == null)
Unit.CaseNumber = " ";
r[CadSupervisorGridCols.Call_Sheet_Number] = Unit.CaseNumber;
r[CadSupervisorGridCols.Call_Sheet_Number_Blank] = Unit.CaseNumber;
r.UserData = Call;
//add unit type images
if(Unit.UnitTypeAbbreviation == "PD")
imageIndex = 2;
else if(Unit.UnitTypeAbbreviation == "EMS")
imageIndex = 0;
else if(Unit.UnitTypeAbbreviation == "FIRE")
imageIndex = 1;
else if(Unit.UnitTypeAbbreviation == "SHF")
imageIndex = 3;
else
imageIndex = 2;
this.grdCad.SetCellImage(r.Index, CadSupervisorGridCols.Unit_Type_Icon, this.imgCallViewImages.Images[imageIndex]);
//format the unit icon cell
C1.Win.C1FlexGrid.CellRange rng = this.grdCad.GetCellRange(r.Index,
CadSupervisorGridCols.Unit_Type_Icon, r.Index,
CadSupervisorGridCols.Unit_Type_Icon);
if(this.NightMode)
{
rng.Style = this.grdCad.Styles["UnitIconFormatDark"];
rng.Style.ForeColor = Color.Transparent;
}
else
{
rng.Style = this.grdCad.Styles["UnitIconFormat"];
}
//color code unit lines
if(Unit.ArriveTime != null)
{
rng = this.grdCad.GetCellRange(r.Index, CadSupervisorGridCols.Dispatch_Unit, r.Index,
CadSupervisorGridCols.Dispatch_Arrive);
if(this.NightMode)
{
rng.Style = this.grdCad.Styles["UnitArriveDark"];
rng.Style.ForeColor = this.NightModeColor;
}
else
{
rng.Style = this.grdCad.Styles["UnitArrive"];
}
}
else if(Unit.EnrouteTime != null)
{
rng = this.grdCad.GetCellRange(r.Index, CadSupervisorGridCols.Dispatch_Unit, r.Index,
CadSupervisorGridCols.Dispatch_Enroute);
if(this.NightMode)
{
rng.Style = this.grdCad.Styles["UnitEnrouteDark"];
rng.Style.ForeColor = this.NightModeColor;
}
else
{
rng.Style = this.grdCad.Styles["UnitEnroute"];
}
}
else if(Unit.AssignTime != null)
{
rng = this.grdCad.GetCellRange(r.Index, CadSupervisorGridCols.Dispatch_Unit, r.Index,
CadSupervisorGridCols.Dispatch_Assign);
if(this.NightMode)
{
rng.Style = this.grdCad.Styles["UnitAssignDark"];
rng.Style.ForeColor = this.NightModeColor;
}
else
{
rng.Style = this.grdCad.Styles["UnitAssign"];
}
}
r.AllowMerging = true;
//if the unit has changed location add the change location line
if(Unit.UnitChangeLocation != null)
{
//add a row
C1.Win.C1FlexGrid.Row RowChangeLocation = this.grdCad.Rows.Add();
//setup the cols
RowChangeLocation[CadSupervisorGridCols.Quick_Call_Num] = Unit.Parent.QuickCallRefrenceNumber;;
RowChangeLocation[CadSupervisorGridCols.Dispatch_Unit] = " Location Change";
RowChangeLocation[CadSupervisorGridCols.Dispatch_Unit_Blank] = " Location Change";
RowChangeLocation[CadSupervisorGridCols.Dispatch_Assign] = AbbreviateTime(Unit.UnitChangeLocationTime);
RowChangeLocation[CadSupervisorGridCols.Dispatch_Enroute] = "Location";
RowChangeLocation[CadSupervisorGridCols.Dispatch_Arrive] = Unit.UnitChangeLocation;
RowChangeLocation[CadSupervisorGridCols.Dispatch_Trans_Start] = Unit.UnitChangeLocation;
RowChangeLocation[CadSupervisorGridCols.Dispatch_Trans_End] = Unit.UnitChangeLocation;
RowChangeLocation[CadSupervisorGridCols.Dispatch_To_Station] = Unit.UnitChangeLocation;
RowChangeLocation[CadSupervisorGridCols.Dispatch_At_Station] = Unit.UnitChangeLocation;
RowChangeLocation[CadSupervisorGridCols.Call_Sheet_Number] = Unit.UnitChangeLocation;
RowChangeLocation[CadSupervisorGridCols.Call_Sheet_Number_Blank] = Unit.UnitChangeLocation;
RowChangeLocation[CadSupervisorGridCols.Unit_Type_Icon] = Unit.UnitNumber;
//call sorting info
RowChangeLocation["RECNO"] = Unit.Parent.RecordNumber;
RowChangeLocation["RECNO1"] = Unit.Parent.RecordNumber;
RowChangeLocation["RECNO2"] = Unit.Parent.RecordNumber;
RowChangeLocation["RECNO3"] = Unit.Parent.RecordNumber;
RowChangeLocation["CALLTIME"] = Unit.Parent.CallReceivedTime;
RowChangeLocation["PRIORITY"] = Unit.Parent.CallPriorityDescription;
RowChangeLocation["CALLTYPE"] = Unit.Parent.CallTypeDescription;
RowChangeLocation["NOTDISPATCHED"] = Unit.Parent.Units.Count == 0 ? 0 : 1;
this.grdCad.SetCellImage(RowChangeLocation.Index, CadSupervisorGridCols.Unit_Type_Icon,
this.imgCallViewImages.Images[imageIndex]);
//set the icon image cell style
C1.Win.C1FlexGrid.CellRange rngIcon = this.grdCad.GetCellRange(RowChangeLocation.Index,
CadSupervisorGridCols.Unit_Type_Icon, RowChangeLocation.Index,
CadSupervisorGridCols.Unit_Type_Icon);
if(this.NightMode)
{
rngIcon.Style = this.grdCad.Styles["UnitIconFormatDark"];
rng.Style.ForeColor = this.NightModeColor;
}
else
{
rngIcon.Style = this.grdCad.Styles["UnitIconFormat"];
}
//color the location text red and bold it, this info is located in the style
//UnitChangeLocationText
C1.Win.C1FlexGrid.CellRange rngLocationText = this.grdCad.GetCellRange(RowChangeLocation.Index,
CadSupervisorGridCols.Dispatch_Arrive, RowChangeLocation.Index,
CadSupervisorGridCols.Call_Type_Blank);
rngLocationText.Style = this.grdCad.Styles["UnitChangeLocationText"];
RowChangeLocation.AllowMerging = true;
this.grdCad.Cols[CadSupervisorGridCols.Unit_Type_Icon].AllowMerging = true;
}
}
catch(Exception _ex)
{
Ems.HandleException(this, _ex, Ems.AsParams(Unit));
}
}
/// <summary>
/// Abbreviates hh:mm:ss time to hh:mm
/// </summary>
private static string AbbreviateTime(string FullTime)
{
if (string.IsNullOrEmpty(FullTime))
{
return FullTime;
}
else
{
return FullTime.Substring(0, 5);
}
}
#endregion
#region AddLine DispatchUnit
/// <summary>
/// Adds active unit data to the active units grid.
/// </summary>
/// <param name="Unit">DispatchUnit</param>
private void AddLine(DispatchUnit Unit)
{
try
{
C1.Win.C1FlexGrid.Row rHeader = this.grdUnits.Rows[0];
C1.Win.C1FlexGrid.CellRange rngHeader = this.grdUnits.GetCellRange(rHeader.Index,
0, rHeader.Index, 2);
C1.Win.C1FlexGrid.Row r = this.grdUnits.Rows.Add();
r.AllowMerging = true;
if(this.NightMode)
{
this.grdUnits.Styles["EmptyArea"].BackColor = Color.Black;
rngHeader.Style = this.grdUnits.Styles["UnitHeaderDark"];
rngHeader.Style.ForeColor = this.NightModeColor;
}
else
{
this.grdUnits.Styles["EmptyArea"].BackColor = SystemColors.Control;
rngHeader.Style = this.grdUnits.Styles["UnitHeader"];
this.grdUnits.BackColor = SystemColors.Window;
}
//Create the dispatch-able unit line
r[0] = Unit.UnitNo + " (" + Unit.NumberOfOfficersInUnit + ")";
r[1] = Unit.TypeSubTypeDescription;
r[2] = Unit.TypeSubTypeDescription;
r["Agency"] = Unit.AgencyDescription;
r["UnitNo"] = Unit.UnitNo;
r["UnitType"] = Unit.TypeDescription;
r.UserData = Unit;
//add the style
C1.Win.C1FlexGrid.CellRange rng = this.grdUnits.GetCellRange(r.Index,
0, r.Index, 2);
if(this.NightMode)
{
rng.Style = this.grdUnits.Styles["UnitNotDispatchedDark"];
rng.Style.ForeColor = this.NightModeColor;
}
else
{
rng.Style = this.grdUnits.Styles["UnitNotDispatched"];
}
//are we dispatched
if(Unit.IsDispatched)
{
if(this.NightMode)
{
rng.Style = this.grdUnits.Styles["UnitAssignDark"];
rng.Style.ForeColor = this.NightModeColor;
}
else
{
rng.Style = this.grdUnits.Styles["UnitAssign"];
}
if(Unit.IsUnitEnroute)
{
if(this.NightMode)
{
rng.Style = this.grdUnits.Styles["UnitEnrouteDark"];
rng.Style.ForeColor = this.NightModeColor;
}
else
{
rng.Style = this.grdUnits.Styles["UnitEnroute"];
}
}
if(Unit.IsUnitArrived)
{
if(this.NightMode)
{
rng.Style = this.grdUnits.Styles["UnitArriveDark"];
rng.Style.ForeColor = this.NightModeColor;
}
else
{
rng.Style = this.grdUnits.Styles["UnitArrive"];
}
}
}
if(Unit.OutOfVehicleLocation != null)
{
rng.Style = this.grdUnits.Styles["OutOfVehicle"];
Unit.IsDispatched = true;
}
if (Unit.IsDispatched)
r["Aval"] = "1";
else
r["Aval"] = "0";
}
catch(Exception _ex)
{
Ems.HandleException(this, _ex, Ems.AsParams(Unit));
}
}
#endregion
#region Public Properties
/// <summary>
/// GET: Provides access to Calls in the calls grid
/// of this control.
/// </summary>
[Browsable(false)]
public MobileCalls Calls
{
get
{
lock (_lock)
{
return _calls;
}
}
}
/// <summary>
/// GET: Provides access to dispatch units in the units grid
/// of this control.
/// </summary>
[Browsable(false)]
public DispatchUnits Units
{
get
{
lock (_lock)
{
return _units;
}
}
}
/// <summary>
/// GET: Provides access to the list of queued units in the calls grid.
/// </summary>
[Browsable(false)]
public QueuedUnits QueuedUnits
{
get
{
lock (_lock)
{
return _qUnits;
}
}
}
/// <summary>
/// GET, SET: CallDisplaySettings instance for grid sorting and
/// call filtering.
/// </summary>
[Browsable(false)]
public CallDisplaySettings CallFilter
{
get
{
lock (_lock)
{
return _settings;
}
}
set
{
lock (_lock)
{
if (value == null)
{
value = new CallDisplaySettings();
}
_settings = value;
}
}
}
/// <summary>
/// SET: Allow unit to assign/de-assign itself.
/// </summary>
[Browsable(false)]
public bool AllowUnitAssign
{
set
{
lock (_lock)
{
_allowUnitAssign = value;
}
}
}
/// <summary>
/// SET: Allow unit to queue/de-queue itself.
/// </summary>
[Browsable(false)]
public bool AllowCallQueuing
{
set
{
lock (_lock)
{
_allowCallQueuing = value;
}
}
}
#endregion
#region ReSortGrids
/// <summary>
/// Resorts Call and Units grids.
/// </summary>
/// <param name="settings">CallDisplaySettings, contains sort information</param>
public void ReSortGrids(CallDisplaySettings settings)
{
lock (_lock)
{
try
{
_settings = settings;
SortUnitsGrid();
SortCallGrid();
}
catch (Exception _ex)
{
Ems.HandleException(this, _ex, Ems.AsParams(settings));
}
}
}
#endregion
#region SetColSortUnitsGrid
/// <summary>
/// Sets up column sorting for the dispatch units grid
/// </summary>
private void SetColSortUnitsGrid()
{
C1.Win.C1FlexGrid.SortFlags f2;
if (0 == _settings.UnitSortDirection)
{
f2 = C1.Win.C1FlexGrid.SortFlags.Descending;
}
else
{
f2 = C1.Win.C1FlexGrid.SortFlags.Ascending;
}
switch (_settings.UnitSort)
{
case 0: // Sort by Unit agency
this.grdUnits.Cols[3].Sort = f2; // 3 = Unit agency
break;
case 1: // Sort by Unit Type
this.grdUnits.Cols[4].Sort = f2; // 4 = Unit Type
break;
case 2: // Sort by Unit Availability
this.grdUnits.Cols[5].Sort = f2; // 5 = Availability
break;
default: // case 3: // Sort by Unit number
this.grdUnits.Cols[6].Sort = f2; // 6 = Unit number
break;
}
}
#endregion
#region SetCollSortCallGrid
/// <summary>
/// Sets up column sorting for the calls grid
/// </summary>
private void SetCollSortCallGrid()
{
foreach(DictionaryEntry de in this._settings.CallSortOptions)
{
SortItem i = (SortItem)de.Value;
C1.Win.C1FlexGrid.SortFlags f;
if(i.SortDirection)
f = C1.Win.C1FlexGrid.SortFlags.Descending;
else
f = C1.Win.C1FlexGrid.SortFlags.Ascending;
if(i.RadioButtonTagValue == "4")
this.grdCad.Cols[14].Sort = f;
if(i.RadioButtonTagValue == "3")
this.grdCad.Cols[16].Sort = f;
if(i.RadioButtonTagValue == "2")
this.grdCad.Cols[18].Sort = f;
if(i.RadioButtonTagValue == "1")
this.grdCad.Cols[20].Sort = f;
}
}
#endregion
#region SortUnitsGrid
/// <summary>
/// Performs Units grid sorting.
/// </summary>
private void SortUnitsGrid()
{
//clear all sort flags
foreach(C1.Win.C1FlexGrid.Column c in this.grdUnits.Cols)
{
c.Sort = SortFlags.None;
}
SetColSortUnitsGrid();
CellRange r = this.grdUnits.GetCellRange(1, 3, grdUnits.Rows.Count - 1, 6);
this.grdUnits.Sort(SortFlags.UseColSort, r);
}
#endregion
#region SortCallGrid
/// <summary>
/// Performs Call grid sorting.
/// </summary>
private void SortCallGrid()
{
foreach(C1.Win.C1FlexGrid.Column c in this.grdCad.Cols)
{
c.Sort = SortFlags.None;
}
SetCollSortCallGrid();
CellRange r = this.grdCad.GetCellRange(1, 13, grdCad.Rows.Count - 1, 20);
this.grdCad.Sort(SortFlags.UseColSort, r);
}
#endregion
#region CallGridPopup
/// <summary>
/// EVENT HANDLER: Raise the CallGridPopupContextMenu event back to host form
/// this control is placed on.
/// </summary>
/// <param name="sender">MenuItem</param>
/// <param name="e">EventArgs</param>
private void CallGridPopup(object sender, System.EventArgs e)
{
ToolStripMenuItem menuItem = (ToolStripMenuItem)sender;
if(CallGridPopupContextMenu != null)
{
int row = (int)this.mnuCallGridPopup.Tag;
if(row > 0 && grdCad.Rows.Count > row)
{
MobileCall call = grdCad.Rows[row].UserData as MobileCall;
if (menuItem == mnuCallGridPopupAssign)
{
if (menuItem.Text.StartsWith("Assign"))
{
CallGridPopupContextMenu(sender, new DispatchSuperEventArgs(DispatchSuperCommandType.Assign, call));
}
else
{
CallGridPopupContextMenu(sender, new DispatchSuperEventArgs(DispatchSuperCommandType.DeAssign, call));
}
}
else if (menuItem == mnuCallGridPopupQueue)
{
if (menuItem.Text.StartsWith("Queue"))
{
CallGridPopupContextMenu(sender, new DispatchSuperEventArgs(DispatchSuperCommandType.Queue, call));
}
else
{
CallGridPopupContextMenu(sender, new DispatchSuperEventArgs(DispatchSuperCommandType.DeQueue, call));
}
}
else
{
CallGridPopupContextMenu(sender, new DispatchSuperEventArgs(DispatchSuperCommandType.CallNotes, call));
}
}
}
}
private void mnuCallGridPopup_Opening(object sender, CancelEventArgs e)
{
toolStripSeparator1.Visible = _allowUnitAssign;
mnuCallGridPopupAssign.Visible = _allowUnitAssign;
mnuCallGridPopupQueue.Visible = _allowCallQueuing && _allowUnitAssign;
}
#endregion
#region UnitsGridPopup
/// <summary>
/// EVENT HANDLER: Raise the UnitsGridPopupContextMenu event back to host form
/// this control is placed on.
/// </summary>
/// <param name="sender">MenuItem</param>
/// <param name="e">EventArgs</param>
private void UnitsGridPopup(object sender, System.EventArgs e)
{
if(UnitsGridPopupContextMenu != null)
{
int row = (int)mnuUnitsGridPopup.Tag;
if(row > 0)
{
DispatchUnit unit = null;
try
{
unit = (DispatchUnit)grdUnits.Rows[row].UserData;
}
catch
{
unit = null;
}
UnitsGridPopupContextMenu(sender, new DispatchSuperEventArgs(DispatchSuperCommandType.UnitInfo, unit));
}
}
}
#endregion
#region grdCad_MouseUp
/// <summary>
/// EVENT HANDLER: Displays the popup context menu for grdCad on Mouse up. The menu item click event
/// is handled from CallGridPopup
/// </summary>
/// <param name="sender">C1.FlexGrid</param>
/// <param name="e">MouseEventArgs</param>
private void grdCad_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
int row = grdCad.MouseRow;
try
{
if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
{
if (CallGridPopupContextMenu != null)
{
if (row > 0 && grdCad[row, CadSupervisorGridCols.Quick_Call_Num] != null
&& grdCad[row, CadSupervisorGridCols.Quick_Call_Num].ToString().Trim() != string.Empty)
{
mnuCallGridPopup.Tag = row;
// If grid row has call data, display the menu
if (grdCad.Rows[row].UserData != null)
{
MobileCall call = (MobileCall)grdCad.Rows[row].UserData;
// Default to active unit not assigned to a call
mnuCallGridPopupAssign.Text = "Assign to This Call";
mnuCallGridPopupQueue.Text = "Queue to This Call";
mnuCallGridPopupAssign.Enabled = true;
mnuCallGridPopupQueue.Enabled = false;
if (_activeUnit.IsAssigned)
{
// default to active unit not assigned to this call
mnuCallGridPopupAssign.Enabled = false;
mnuCallGridPopupQueue.Enabled = true;
// Check to see if active unit is assigned to this call.
foreach (DictionaryEntry de in call.Units)
{
MobileUnit u = (MobileUnit)de.Value;
// If active unit is assigned to this call, set to De-Assign
if (!string.IsNullOrEmpty(u.AssignTime) && u.UnitID == _activeUnit.UnitID)
{
mnuCallGridPopupAssign.Text = "De-Assign Yourself";
mnuCallGridPopupQueue.Enabled = false;
// If active unit has not arrived, enable De-Assign
if (string.IsNullOrEmpty(u.ArriveTime))
{
mnuCallGridPopupAssign.Enabled = true;
}
break;
}
}
// check to see if active unit is queued to this call.
if (_qUnits != null)
{
foreach (QueuedUnit qu in _qUnits.ToList())
{
if (qu.UnitNumber == _activeUnit.UnitNo && qu.CallRecordNumber == call.RecordNumber)
{
mnuCallGridPopupQueue.Text = "De-Queue Yourself";
break;
}
}
}
}
// Display the menu
grdCad.ContextMenuStrip = this.mnuCallGridPopup;
grdCad.ContextMenuStrip.Show(grdCad, new Point(e.X, e.Y));
}
}
}
}
}
catch(Exception _ex)
{
Ems.HandleException(this, _ex, Ems.AsParams(sender, e));
}
finally
{
//keeps the context menu from showing.
grdCad.ContextMenuStrip = null;
}
}
#endregion
#region grdUnits_MouseUp
/// <summary>
/// EVENT HANDLER: Displays the popup context menu for grdUnits on Mouse up. The menu item click event
/// is handled from UnitsGridPopup.
/// </summary>
/// <param name="sender">C1.FlexGrid</param>
/// <param name="e">MouseEventArgs</param>
private void grdUnits_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
int row = grdUnits.MouseRow;
try
{
if(e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
{
if(UnitsGridPopupContextMenu != null)
{
if(row > 0)
{
this.mnuUnitsGridPopup.Tag = row;
grdUnits.ContextMenuStrip = this.mnuUnitsGridPopup;
grdUnits.ContextMenuStrip.Show(grdUnits, new Point(e.X, e.Y));
}
}
}
}
catch(Exception _ex)
{
Ems.HandleException(this, _ex, Ems.AsParams(sender, e));
}
finally
{
//keeps the context menu from showing.
grdUnits.ContextMenuStrip = null;
}
}
#endregion
}