ガントチャート作成日記

行や列を見やすくするために別のDataTemplateを表現するようにした。



バインドする全体のGanttCellを格納するGanttGridCellsと列や行を分けて格納しておく
GanttGridRowCells やGanttGridColumnCells を新たに追加した。

public GanttGridViewModel()
{
    this.GanttGridCells = new ObservableCollection<GanttCell>();
    this.GanttGridRowCells = new ObservableCollection<GanttCell>();
    this.GanttGridColumnCells = new ObservableCollection<GanttCell>();
    this.GanttGridTaskCells = new ObservableCollection<GanttCell>();

    GanttHeader h = new GanttHeader();
 
    h.ColumnCount = this.ColumnCount;
    h.ColumnWidth = this.ColumnWidth;

    ObservableCollection<GanttHeaderCell> topCells = new ObservableCollection<GanttHeaderCell>();
    ObservableCollection<GanttHeaderCell> bottomCells = new ObservableCollection<GanttHeaderCell>();

    int colSpanCnt = 0;
    for (int i = 0; i <= this.ColumnCount; i++)
    {
        DateTime d = DateTime.Now.AddDays(i);
        if (d.ToString("dd") == "01" || i == 0)
        {
            int iDaysInMonth = DateTime.DaysInMonth(d.Year, d.Month);
            colSpanCnt = iDaysInMonth - int.Parse(d.ToString("dd")) + 1;
            topCells.Add(new GanttHeaderCell() { ColumnIndex = i, RowIndex = 0, ColumnSpan = colSpanCnt, Date = d });
        }
        bottomCells.Add(new GanttHeaderCell() { ColumnIndex = i, RowIndex = 0, Date = d });
    }

    h.BottomHeaderCells = bottomCells;
    h.TopHeaderCells = topCells;

    TimeSpan ts = DateTime.Now.AddYears(1) - DateTime.Now;
    h.ColumnCount = ts.Days;

    this.Header = h;


    // タスクを表現するセルを追加
    for (int i = 0; i < 500; i++)
    {
        this.GanttGridTaskCells.Add(new GanttCell() { RowIndex = i, RowSpan = 1, ColumnIndex = i, ColumnSpan = 2, DataTemplateType = GanttCell.TemplateType.Task });
    }

    // タスクの数だけ行を表現するセルを追加
    for (int i = 0; i < this.GanttGridTaskCells.Count - 1; i++)
    {
        if (i % 2 == 0)
        {
            this.GanttGridRowCells.Add(new GanttCell() { RowIndex = i, RowSpan = 1, ColumnIndex = 0, ColumnSpan = 365, DataTemplateType = GanttCell.TemplateType.RowLine });
        }
        else
        {
            this.GanttGridRowCells.Add(new GanttCell() { RowIndex = i, RowSpan = 1, ColumnIndex = 0, ColumnSpan = 365, DataTemplateType = GanttCell.TemplateType.AlternateRowLine });
        }
    }

    // 列の数だけ列を表現するセルを追加
    foreach (var item in this.Header.BottomHeaderCells)
    {
        string week = item.Date.ToString("ddd");
        GanttCell.TemplateType type = GanttCell.TemplateType.ColumnLine;
        if (week == "日")
        {
            type = GanttCell.TemplateType.ColumnLineOrange;
        }
        else if (week == "土")
        {
            type = GanttCell.TemplateType.ColumnLineBlue;
        }
        else if (Common.Holiday(item.Date).holiday != Common.HolidayInfo.HOLIDAY.WEEKDAY)
        {
            // 平日以外(祝日・振替休日)の場合は日と同じ色を設定
            type = GanttCell.TemplateType.ColumnLineOrange;
        }

        this.GanttGridColumnCells.Add(new GanttCell() { RowIndex = 0, ColumnIndex = item.ColumnIndex, ColumnSpan = 1, RowSpan = this.GanttGridTaskCells.Count, DataTemplateType = type });
    }

    //バインディングするためのセルを作成する
    foreach (var item in this.GanttGridColumnCells) { this.GanttGridCells.Add(item); }
    foreach (var item in this.GanttGridRowCells) { this.GanttGridCells.Add(item); }
    foreach (var item in this.GanttGridTaskCells) { this.GanttGridCells.Add(item); }

}

バインドされているのはGanttGridCellsプロパティだが見た目を変更するためにDataTemplateSelectorを継承したGanttGridTemplateSelecterを作成している。

GanttGridTemplateSelecterはGanttGrid.xamlで利用している
ItemsControlのItemTemplateSelectorに設定している。
各DataTemplateはUserControlのResourcesに定義しておいて、GanttGridCellsがバインドされたらバインドされているGanttCellのDataTemplateTypeプロパティに応じて利用するDateTemplateを切り替えている。

詳細はソースを参照。
前回アップしたものとWinMergeなどで比較するとわかりやすい。

ついでにDataGridにGanttGridTaskCellsをバインドすることで、ガントチャートっぽくなった。DataGridをスクロールしたときに同期するようにしてみた。
ガントチャート側をスクロールしたときにもスクロールするようにしたりする必要はある。

横に出すのをDataGridのような一覧にするか、移動、リサイズ可能なTextBoxを作成して、それをバインドするか悩むところ。
せっかくなんでいろんなソフトを作ってみようかと思う。

DataGridで階層を表現できると一番いいけど・・・。
セルのマージは難しそうだし、悩ましい。

<DownLoad>

0 件のコメント:

コメントを投稿

PowerShellでEdgeを自動化(インストール不要。参考:郵便追跡サービス自動操作)

1.経緯について  RPAのソフトをインストールできないので、これまでVBSでCreateObjectでブラウザの自動操作をすることがたまにあった。 ※いざというときの手札として持っているだけで安心感が段違い  見た目上IEがインストールされていなくても、CreateObject...