Introduction
I was recently involved in developing a schedule management system using the Gantt Model provided by the C# .NET Framework. I extended ActivityDialog
and designed a new dialog that handles customer-specific activity, resource, constraint, and reservation. In this project, I was confronted with a difficulty: how to handle a GanttChart
on ActivityDialog
. I give you my solution for the problem in this article.
Background
I added a new TabPage
(includes a DataGridView
) on the ActivityDialog
to be able to add/delete/update a new constraint of activity. This DataGridView
has two columns (activity and lead time). The activity combobox column means the From-Activity of the constraint. The requirement is to display the selected activity on the GanttChart
when you add a new constraint on the ActivityDialog
.
Using the code
I needed new combobox to handle the GanttChart
, so I defined the DataGridViewExtendedComboBoxColumn
class for the activity combo box. In this class, I overrode InitializeEditingControl
to add two event handlers: the SelectedIndexChanged
handler displays the selected activity on the GanttChart
.
public class ProgressActivityDialog : ILOG.Views.Gantt.Windows.Forms.ActivityDialog
{
public ProgressActivityDialog(InitParamActivityDialog param)
{
}
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
if (this.Visible)
{
if ((this.tabControl.TabPages == null) ||
(this.tabControl.TabPages.Count == 0) ||
(this.currentActivity == null))
{
return;
}
this.tabControl.TabPages.Remove(predecessorsTab);
if (currentActivity.BNodeLevel != (int)ActivityNodeLevel.Kojun)
{
this.tabControl.TabPages.Remove(resourcesTab);
}
if (currentActivity.BEventFlg == 1)
{
this.resourcesLabel.Visible = false;
this.resourcesGrid.Visible = false;
this.resourceNewGrid.Visible = false;
}
if (initParams.dialogType == EnumDialogType.ScheduleOrganization)
{
if ((initParams.isNewActivity) &&
(currentActivity.BNodeLevel == (int)ActivityNodeLevel.Kojun))
{
if (currentActivity.BEventFlg == 0)
{
currentActivity.StartTime = DateTime.Now.Date + new TimeSpan(8, 0, 0);
currentActivity.EndTime = DateTime.Now.Date + new TimeSpan(17, 0, 0);
currentActivity.Duration = new TimeSpan(9, 0, 0);
}
else
{
currentActivity.StartTime = DateTime.Now.Date + new TimeSpan(8, 0, 0);
currentActivity.EndTime = currentActivity.StartTime;
currentActivity.Duration = new TimeSpan(0, 0, 0);
}
this.startDateTimePicker.Value = currentActivity.StartTime;
this.finishDateTimePicker.Value = currentActivity.EndTime;
}
}
tabControl.SelectedIndexChanged +=
new EventHandler(TabControl_SelectedIndexChanged);
kojunNameCombo.SelectedIndexChanged +=
new EventHandler(KojunNameCombo_SelectedIndexChanged);
eventNameCombo.SelectedIndexChanged +=
new EventHandler(EventNameCombo_SelectedIndexChanged);
ignoreCalendarChkBox.CheckedChanged +=
new EventHandler(IgnoreCalendarChkBox_CheckedChanged);
this.noteTextBox.Clear();
if (currentActivity.BNodeLevel == (int)ActivityNodeLevel.Kojun)
{
this.noteTextBox.Text = currentActivity.BCmnt;
}
}
}
private void SetPredecessorNewGridColumns()
{
predecessorsNewGrid.Columns.Clear();
DataGridViewExtendedComboBoxColumn activityCombo =
new DataGridViewExtendedComboBoxColumn();
activityCombo.relatedGanttChart = initParams.ganttChart;
activityCombo.DataPropertyName = "Activity";
activityCombo.DisplayMember = "NODE_NM";
activityCombo.ValueMember = "NODE_ID";
SetItemsonConstraintFromActivityNameComboBoxColumn(
this.Activity.GanttModel.Activities, activityCombo);
predecessorsNewGrid.Columns.Add(activityCombo);
DataGridViewTextBoxColumn leadTimeText = new DataGridViewTextBoxColumn();
leadTimeText.DataPropertyName = "leadTime";
predecessorsNewGrid.Columns.Add(leadTimeText);
}
internal class DataGridViewExtendedComboBoxCell : DataGridViewComboBoxCell
{
public override void InitializeEditingControl(int rowIndex,
object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
if (base.DataGridView != null)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue,
dataGridViewCellStyle);
ComboBox comboBox = base.DataGridView.EditingControl as ComboBox;
if (comboBox != null)
{
comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
comboBox.SelectedIndexChanged +=
new EventHandler(comboBox_SelectedIndexChanged);
comboBox.Leave += new EventHandler(comboBox_Leave);
}
}
}
private void comboBox_Leave(object sender, EventArgs e)
{
ComboBox comboBox = base.DataGridView.EditingControl as ComboBox;
if (comboBox != null)
{
comboBox.SelectedIndexChanged -=
new EventHandler(comboBox_SelectedIndexChanged);
}
comboBox.Leave -= new EventHandler(comboBox_Leave);
}
private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (base.DataGridView != null)
{
DataGridViewComboBoxEditingControl cbo =
sender as DataGridViewComboBoxEditingControl;
if ((cbo.Text.Trim() != string.Empty) &&
(cbo.FindStringExact(cbo.Text) != -1))
{
DataGridViewExtendedComboBoxColumn column =
(this.DataGridView.Columns[0]) as DataGridViewExtendedComboBoxColumn;
if (column != null)
{
if (column.relatedGanttChart != null)
{
GanttChart ganttChart = column.relatedGanttChart;
ProgressActivity selectedActivity =
(ProgressActivity)ganttChart.GanttModel.FindActivity(
(string)cbo.SelectedValue);
ganttChart.GanttTable.ExpandAll();
SetFirstVisibleActivityOnGanttChart(ganttChart, selectedActivity);
}
}
}
}
}
private void SetFirstVisibleActivityOnGanttChart(GanttChart ganttChart,
ProgressActivity activity)
{
if (activity.StartTime != DateTime.Parse("0001/1/1"))
{
ganttChart.FirstVisibleTime = activity.StartTime;
}
ganttChart.FirstVisibleRow = ganttChart.GanttTable.IndexOfRow(activity);
}
}
internal class DataGridViewExtendedComboBoxColumn : DataGridViewComboBoxColumn
{
public GanttChart relatedGanttChart = null;
public DataGridViewExtendedComboBoxColumn()
{
DataGridViewExtendedComboBoxCell comboBoxCell =
new DataGridViewExtendedComboBoxCell();
this.CellTemplate = comboBoxCell;
}
}
}
Points of Interest
This sample shows a way to handle GanttChart
by selecting a combo box element on an ActivityDialog
.