private void Form_Load(object sender, EventArgs e)
        {
            List<UDT.Question> Questions = new List<UDT.Question>();
            List<UDT.QuestionOption> QuestionOptions = new List<UDT.QuestionOption>();
            Dictionary<UDT.Hierarchy, List<UDT.Question>> dicHierarchies = new Dictionary<UDT.Hierarchy, List<UDT.Question>>();
            Dictionary<int, List<UDT.QuestionOption>> dicQuestionOptions = new Dictionary<int, List<UDT.QuestionOption>>();
            Dictionary<string, UDT.Question> dicQuestions = new Dictionary<string, UDT.Question>();
            Dictionary<UDT.Hierarchy, List<UDT.Question>> dicHierarchies_New = new Dictionary<UDT.Hierarchy, List<UDT.Question>>();
            this.HTML_Show_Wait();

            Task task = Task.Factory.StartNew(() =>
            {
                List<int> exits_question_ids = new List<int>();
                Questions = Access.Select<UDT.Question>(string.Format("ref_survey_id ={0}", this._Survey.UID));
                if (Questions.Count > 0)
                {
                    QuestionOptions = Access.Select<UDT.QuestionOption>(string.Format("ref_question_id in ({0})", string.Join(",", Questions.Select(x => x.UID))));
                    Questions = Questions.OrderBy(x => x.DisplayOrder).ToList();
                    dicQuestions = Questions.ToDictionary(x=>x.UID);
                }
                if (QuestionOptions.Count > 0)
                    QuestionOptions = QuestionOptions.OrderBy(x => x.QuestionID).ThenBy(x => x.DisplayOrder).ToList();

                List<UDT.QHRelation> QHRelations = Access.Select<UDT.QHRelation>();
                List<UDT.Hierarchy> Hierarchies = Access.Select<UDT.Hierarchy>();
                UDT.Hierarchy uHierarchy = new UDT.Hierarchy();
                dicHierarchies.Add(uHierarchy, new List<UDT.Question>());
                if (Hierarchies.Count > 0)
                {
                    Hierarchies = Hierarchies.OrderBy(x=>x.DisplayOrder).ToList();
                    Hierarchies.ForEach((x) =>
                    {
                        if (!dicHierarchies.ContainsKey(x))
                            dicHierarchies.Add(x, new List<UDT.Question>());
                    });
                }
                if (QHRelations.Count > 0)
                {
                    QHRelations.ForEach((x) =>
                    {
                        foreach (UDT.Hierarchy Hierarchy in dicHierarchies.Keys)
                        {
                            if (x.HierarchyTitle == Hierarchy.Title && dicQuestions.ContainsKey(x.QuestionID.ToString()))
                            {
                                dicHierarchies[Hierarchy].Add(dicQuestions[x.QuestionID.ToString()]);
                                exits_question_ids.Add(x.QuestionID);
                            }
                        }
                    });
                }
                foreach (UDT.QuestionOption QuestionOption in QuestionOptions)
                {
                    if (!dicQuestionOptions.ContainsKey(QuestionOption.QuestionID))
                        dicQuestionOptions.Add(QuestionOption.QuestionID, new List<UDT.QuestionOption>());

                    dicQuestionOptions[QuestionOption.QuestionID].Add(QuestionOption);
                }
                foreach (UDT.Question Q in Questions)
                {
                    if (!exits_question_ids.Contains(int.Parse(Q.UID)))
                    {
                        exits_question_ids.Add(int.Parse(Q.UID));
                        dicHierarchies[uHierarchy].Add(Q);
                    }
                }
                foreach (UDT.Hierarchy Hierarchy in dicHierarchies.Keys)
                {
                    dicHierarchies_New.Add(Hierarchy, dicHierarchies[Hierarchy].OrderBy(y => y.DisplayOrder).ToList());
                }
            });
            task.ContinueWith((x) =>
            {
                if (Questions.Count == 0)
                {
                    MessageBox.Show("沒有題目。");
                    this.Close();
                    return;
                }
                this.HTML_Preview(Questions, dicQuestionOptions, dicHierarchies_New);

            }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
        }
        private void InitQuestion()
        {
            Dictionary<int, List<UDT.QuestionOption>> dicQuestionOptions = new Dictionary<int, List<UDT.QuestionOption>>();
            Dictionary<UDT.Hierarchy, List<UDT.Question>> dicHierarchies = new Dictionary<UDT.Hierarchy, List<UDT.Question>>();
            Dictionary<UDT.Hierarchy, List<UDT.Question>> dicHierarchies_New = new Dictionary<UDT.Hierarchy, List<UDT.Question>>();

            Task task = Task.Factory.StartNew(() =>
            {
                List<int> exits_question_ids = new List<int>();
                List<UDT.Question> Questions = Access.Select<UDT.Question>(string.Format("ref_survey_id = {0}", this.detailPane1.PrimaryKey));
                List<UDT.QuestionOption> QuestionOptions = new List<UDT.QuestionOption>();
                Dictionary<string, UDT.Question> dicQuestions = new Dictionary<string, UDT.Question>();
                if (Questions.Count > 0)
                {
                    QuestionOptions = Access.Select<UDT.QuestionOption>(string.Format("ref_question_id in ({0})", string.Join(",", Questions.Select(x => x.UID))));
                    Questions = Questions.OrderBy(x => x.DisplayOrder).ToList();
                    dicQuestions = Questions.ToDictionary(x => x.UID);
                }
                if (QuestionOptions.Count > 0)
                    QuestionOptions = QuestionOptions.OrderBy(x => x.QuestionID).ThenBy(x => x.DisplayOrder).ToList();

                List<UDT.QHRelation> QHRelations = Access.Select<UDT.QHRelation>();
                List<UDT.Hierarchy> Hierarchies = Access.Select<UDT.Hierarchy>();
                UDT.Hierarchy uHierarchy = new UDT.Hierarchy();
                dicHierarchies.Add(uHierarchy, new List<UDT.Question>());
                if (Hierarchies.Count > 0)
                {
                    Hierarchies = Hierarchies.OrderBy(x => x.DisplayOrder).ToList();
                    Hierarchies.ForEach((x) =>
                    {
                        if (!dicHierarchies.ContainsKey(x))
                            dicHierarchies.Add(x, new List<UDT.Question>());
                    });
                }
                if (QHRelations.Count > 0)
                {
                    QHRelations.ForEach((x) =>
                    {
                        foreach (UDT.Hierarchy Hierarchy in dicHierarchies.Keys)
                        {
                            if (x.HierarchyTitle == Hierarchy.Title && dicQuestions.ContainsKey(x.QuestionID.ToString()))
                            {
                                dicHierarchies[Hierarchy].Add(dicQuestions[x.QuestionID.ToString()]);
                                exits_question_ids.Add(x.QuestionID);
                            }
                        }
                    });
                }
                foreach (UDT.QuestionOption QuestionOption in QuestionOptions)
                {
                    if (!dicQuestionOptions.ContainsKey(QuestionOption.QuestionID))
                        dicQuestionOptions.Add(QuestionOption.QuestionID, new List<UDT.QuestionOption>());

                    dicQuestionOptions[QuestionOption.QuestionID].Add(QuestionOption);
                }
                foreach (UDT.Question Q in Questions)
                {
                    if (!exits_question_ids.Contains(int.Parse(Q.UID)))
                    {
                        exits_question_ids.Add(int.Parse(Q.UID));
                        dicHierarchies[uHierarchy].Add(Q);
                    }
                }
                foreach (UDT.Hierarchy Hierarchy in dicHierarchies.Keys)
                {
                    dicHierarchies_New.Add(Hierarchy, dicHierarchies[Hierarchy].OrderBy(y => y.DisplayOrder).ToList());
                }
            });
            task.ContinueWith((x) =>
            {
                foreach (UDT.Hierarchy Hierarchy in dicHierarchies_New.Keys)
                {
                    foreach (UDT.Question Question in dicHierarchies_New[Hierarchy])
                    {
                        PrivateControl.DetailContent DetailContent = new DetailContent();
                        if (Question.Type == "單選題")
                            DetailContent = QuestionTemplate.TemplatePool.GetTemplate<QuestionTemplate.SingleChoice>();
                        else if (Question.Type == "問答題")
                            DetailContent = QuestionTemplate.TemplatePool.GetTemplate<QuestionTemplate.Essay>();
                        else if (Question.Type == "複選題")
                            DetailContent = QuestionTemplate.TemplatePool.GetTemplate<QuestionTemplate.MultiChoice>();
                        else
                            throw new Exception("Type:" + Question.Type + ",尚未支援。");

                        DetailContent.Record = Question;
                        DetailContent.PrimaryKey = this.PrimaryKey;
                        DetailContent.SurveyID = int.Parse(this.PrimaryKey);
                        DetailContent.HierarchyTitle = Hierarchy.Title;

                        DetailContent.HierarchyTitleSource = ((new List<string>() { "" }).Union(dicHierarchies_New.Keys.Select(y => y.Title + ""))).Distinct().ToList();

                        if (dicQuestionOptions.ContainsKey(int.Parse(Question.UID)))
                            DetailContent.RecordDetails = dicQuestionOptions[int.Parse(Question.UID)];
                        else
                            DetailContent.RecordDetails = new List<UDT.QuestionOption>();

                        this.AddDetailItem(DetailContent);
                        DetailContent.DataBind();
                    }
                }
                this.detailPane1.PrimaryKey = this.PrimaryKey;
                this.detailPane1.panProgress.Height = 0;
                this.detailPane1.DetailItemContainers.ResumeLayout(false);
                this.detailPane1.DetailItemContainers.Visible = true;
                this.lstSurvey.Enabled = true;
            }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
        }
        private void Save_Click(object sender, EventArgs e)
        {
            if (!Is_Validate())
            {
                MessageBox.Show("請先修正錯誤。");
                return;
            }

            string msg = string.Empty;
            List<UDT.QHRelation> QHRelations = Access.Select<UDT.QHRelation>();
            List<UDT.QHRelation> QHRelations_New = new List<UDT.QHRelation>();
            Dictionary<string, List<UDT.QHRelation>> dicQHRelations = new Dictionary<string, List<UDT.QHRelation>>();
            if (QHRelations.Count > 0)
            {
                QHRelations.ForEach((x) =>
                {
                    if (!dicQHRelations.ContainsKey(x.HierarchyTitle.Trim()))
                        dicQHRelations.Add(x.HierarchyTitle.Trim(), new List<UDT.QHRelation>());

                    dicQHRelations[x.HierarchyTitle.Trim()].Add(x);
                });
            }
            this.Save.Enabled = false;
            List<UDT.Hierarchy> udts = this.Access.Select<UDT.Hierarchy>();
            udts.ForEach(x => x.Deleted = true);
            udts.SaveAll();
            udts.Clear();
            this.dgvData.Rows.Cast<DataGridViewRow>().ToList().ForEach((x) =>
            {
                if (!x.IsNewRow)
                {
                    UDT.Hierarchy udt = new UDT.Hierarchy();

                    udt.Title = (x.Cells[0].Value + "").Trim();
                    udt.DisplayOrder = int.Parse(x.Cells[1].Value + "");

                    udts.Add(udt);

                    if ((x.Cells[0].Tag + "").Trim() != (x.Cells[0].Value + "").Trim())
                    {
                        if (dicQHRelations.ContainsKey((x.Cells[0].Tag + "").Trim()))
                        {
                            foreach (UDT.QHRelation QHRelation in dicQHRelations[(x.Cells[0].Tag + "").Trim()])
                            {
                                QHRelation.HierarchyTitle = (x.Cells[0].Value + "").Trim();
                                QHRelations_New.Add(QHRelation);
                            }
                        }
                    }
                }
            });
            udts.SaveAll();
            QHRelations_New.SaveAll();
            this.DataBind();
            this.Save.Enabled = true;
            MessageBox.Show("儲存成功。");
        }